当useEffect已经适用时,道具更改时加载useState

时间:2020-05-23 22:01:47

标签: reactjs react-hooks use-effect use-state

我正在尝试在更改道具时更新我的​​初始状态,但即使使用useEffect也不起作用。这是我的以下代码: 从图片链接中,您可以看到初始状态已从(p4,p1,p3,p5)更新为(p4,p1,p3,p2),但是useEffect并未触发更改状态,因此状态保持在(p4,p1,p3,p2)。我不知道为什么,而且已经奋斗了几个小时,有人可以帮助我吗?

export default (props) => {
  let toollist = props.getData;
  const inistate = {};

  for (let index in toollist) {
    let stkey = (toollist[index].ttype + toollist[index].toolid)
    inistate[stkey] = [0, 0, 120, 120, false]
  }

  inistate.dragging = false
  inistate.resize = false

  console.log("ini:", inistate)

  const [state, setstate] = useState(inistate)

  useEffect(() => {
    console.log("effected")
    setstate(inistate)
  }, [inistate])

  console.log("state:", state)

enter image description here

对于(getDerivedStateFromProps /移动到父组件网络)(对于Mr.carlosbf):

 export default(props)=>{  
const [state,setstate]=useState({});
const [prevstate,setprevstate]=useState(null);
if (props.ini !== prevstate){
    console.log("changed")
    setstate(props.ini)
    setprevstate(props.ini)
    }
console.log("state:",state)

对于useMemo(对于MR.HMR):

let toollist=props.getData; 
const inistate = useMemo(() => {
    console.log("memoed")
    var inistate = {};
    for (let index in toollist) {
        let stkey = (toollist[index].ttype + toollist[index].toolid)
        inistate[stkey] = [0, 0, 120, 120, false]
    }
    inistate.dragging=false
    inistate.resize=false
    return inistate
}, [toollist])
console.log(inistate)

const[state, setstate]=useState(inistate)

useEffect(()=>{
    console.log(1);
    setstate(inistate);
},[inistate]);

For Mr.HMR (second picture)

2 个答案:

答案 0 :(得分:0)

您好,您似乎在无条件接收道具后试图更改状态,这是一种反模式。 https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html

您可以尝试将此逻辑推向组件树。或通过钩子https://reactjs.org/docs/hooks-faq.html#how-do-i-implement-getderivedstatefromprops实现to=get_user_model()

答案 1 :(得分:0)

我认为您没有正确使用useMemo,这是一个示例,该示例使用useMemo返回一个值,该值用于在初始化更改时再次用钩子设置状态:

const Component = (props) => {
  const toollist = props.getData;
  const inistate = React.useMemo(() => {
    //do whatever you need to create state here
    return toollist;
  }, [toollist]);
  const [state, setstate] = React.useState(inistate);

  React.useEffect(() => {
    setstate(inistate);
  }, [inistate]);

  return (
    <pre>
      state in component:
      {JSON.stringify(state, undefined, 2)}
    </pre>
  );
};
const App = () => {
  const [state, setState] = React.useState({ counter: 0 });
  return (
    <div>
      <button
        onClick={() =>
          setState({ ...state, counter: state.counter + 1 })
        }
      >
        change state
      </button>
      <Component getData={state} />
    </div>
  );
};
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>


<div id="root"></div>