useRef使用

61 阅读1分钟
  useEffect,
  useState,
  useMemo,
  useRef,
  forwardRef,
  createRef,
  useImperativeHandle,
  useReducer,
} from 'react';
import { CnPage } from '@alife/cn-ui';
import * as _ from 'lodash';
import './index.scss';
import { DemoTs } from './demo';

function DemoTsFu() {
  const [use, setUse] = useState([]);
  const click = () => {
    var obj = new DemoTs();
    obj.getName();
    let useInfo = obj.useInfo;
    console.log('==useInfo=', useInfo);
  };
  useEffect(() => {
    var obj = new DemoTs();
    obj.getName();
    let useInfo = obj.useInfo;
    console.log('==useInfo=', useInfo);
    setUse(useInfo);
  }, []);
  return (
    <CnPage>
      {use.length > 0 &&
        use.map((item) => (
          <div>
            {item.name}-{item.age}
          </div>
        ))}
      <div onClick={click}>点</div>
    </CnPage>
  );
}

function ChildA({ name, children }) {
  const use = <a>我是{name}</a>;
  return <div>我是children - {children(use)}</div>;
}

function ChildrenDemo(props) {
  const name = '张三';
  return (
    <ChildA name={name}>{(info) => <span>我是回调 - {info} </span>}</ChildA>
  );
}

// 调用子元素回调 numTimes 次,来重复生成组件
function Repeat({ useInfo, children }) {
  return useInfo?.map((item, idx) =>
    children({
      index: idx,
      info: item.name + '- ' + item.age,
    }),
  );
}

function ListOfTenThings() {
  const useInfo = [
    { name: '章三', age: '12' },
    { name: '李四', age: '18' },
  ];
  return (
    <Repeat useInfo={useInfo}>
      {({ index, info }) => <p key={index}>用户信息:{info}</p>}
    </Repeat>
  );
}

const Child = forwardRef((props, ref) => {
  const valueRef = useRef(null);
  // useEffect(() => {
  //   valueRef.current = { value: '初始值' };
  // });
  const [userInfo, setUserInfo] = useState(1);
  const onChange = () => {
    setUserInfo((e) => e + 1);
  };
  useImperativeHandle(ref, () => ({
    setValue: () => {
      onChange();
    },
    getValue: () => {
      setUserInfo(valueRef.current.value);
      console.log('数据', valueRef.current.value);
    },
  }));
  return (
    <div>
      子组件 = {props.children}
      <input type='text' ref={valueRef} />
      {userInfo}
    </div>
  );
});

const ChildB = ({ getChildData, childDom }) => {
  const [name, setName] = useState('张三');
  const say = () => {
    setName((e) => '我是' + e);
  };
  const click = () => {
    getChildData({ data: name, way: say });
  };
  return (
    <>
      <div>{childDom}</div>
      <div onClick={click}>点击</div>
    </>
  );
};

const components = {
  photo: (props) => {
    let showInfo = props.name;
    if (props.age > 18) {
      showInfo += '成年了,' + props.age;
    } else {
      showInfo += props.age;
    }
    return <>子组件1 {showInfo}</>;
  },
  video: (props) => {
    return <>子组件2 {props.name}</>;
  },
};

const Index = () => {
  const [userInfo, setUserInfo] = useState('初始值');
  const [propsType, setPropsType] = useState('photo');
  const [age, setAge] = useState(11);

  const parentWay = (data) => {
    setUserInfo('父-' + data);
  };
  const getChildData = ({ data, way }) => {
    if (data === '我是张三') {
      parentWay(data);
    } else {
      setUserInfo(data);
    }
    way();
  };
  const childRef = useRef(null);
  const inputRef = useRef(null);
  const search = () => {
    childRef.current.setValue();
  };
  const getData = () => {
    childRef.current.getValue();
  };

  const SpecificStory = components[propsType];

  // const reduceSum = useMemo(() => {
  //   console.log('===reduceData,', reduceData);
  //   // reduceData?.reduce((res, [key, value]) => {
  //   //   console.log(res, key, value);
  //   //   return res + value;
  //   // });
  //   return 'aa';
  // }, [reduceData]);

  let reduceData = [{ age: 1 }, { age: 2 }, { age: 3 }, { age: 4 }, { age: 5 }];
  const reduceSum = () => {
    return reduceData.reduce((res, value) => {
      return res + value.age;
    }, null);
  };

  const reduceFun = () => {
    // reduceData.reduce(function (
    //   previousValue,
    //   currentValue,
    //   currentIndex,
    //   array,
    // ) {
    //   console.log(previousValue, currentValue, currentIndex, array);
    // },
    // 0);
  };

  return (
    <CnPage>
      <div>
        累加 {reduceSum()} == {reduceFun()}
      </div>
      <h4>回调使用</h4>
      <ChildrenDemo />
      <ListOfTenThings />
      ref 使用
      <Child ref={childRef}>
        <h2>children 我是插槽内容</h2>
      </Child>
      <div onClick={search}>触发方法</div>
      <div onClick={getData}>获取值</div> <br />
      <br />
      父向子传值 通过方法可回调 <br />
      {userInfo}
      <ChildB {...{ getChildData, childDom: <span>开始执行===</span> }} />
      <br />
      <br />
      使用. 组件
      <div onClick={() => setPropsType('photo')}>选中photo</div>
      <div onClick={() => setPropsType('video')}>选中video</div>
      <input
        type='text'
        ref={inputRef}
        onChange={() => setAge(inputRef.current.value)}
      />
      <SpecificStory name={propsType} age={age} />
    </CnPage>
  );
};

export default DemoTsFu;