【问题标题】:Loading useState when props changes when useEffect already applies当 useEffect 已经应用时,当 props 改变时加载 useState
【发布时间】:2020-05-23 22:01:47
【问题描述】:

我正在尝试在更改道具时更新我的​​初始状态,但即使使用 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

For (getDerivedStateFromProps/moveup to parent componenet) (For 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)

【问题讨论】:

  • 尝试将initState 设置为useMemo 的结果,该结果将取决于props.getData,然后每次props.getData 更改而不是每次组件呈现时都会运行效果。跨度>
  • 嗨,HMR 先生,您的意思是像我的编辑吗?当我运行程序时,useMemo 确实触发了,但不知何故,状态并没有随 Setstate 改变,所以它仍然是空的。抱歉,我还是 React 新手,也许我错过了一些重要的东西。

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


【解决方案1】:

您好,您似乎正试图在无条件接收道具后更改状态,这是一种反模式。 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 实现getDerivedStateFromProps

【讨论】:

  • 对不起,我对此还是很陌生。是不是和我刚刚编辑的一样?它确实进入了 if 循环,但 setstate 似乎没有以某种方式触发。
【解决方案2】:

我认为你没有正确使用 useMemo,这是一个使用 useMemo 返回值的示例,该值用于在 inistate 更改时再次设置状态:

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>

【讨论】:

猜你喜欢
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2018-12-04
  • 1970-01-01
相关资源
最近更新 更多