使用useEffect挂钩更新状态变化时的地图功能

时间:2020-10-14 18:00:56

标签: reactjs dictionary react-hooks state

我相信我了解useEffect挂钩的工作原理,但是当从父组件发送的道具发生更改时,我很难重新渲染组件以更新map函数。

useEffect(() => console.log('mounted'), []);

我的理解是,当第二个参数的任何值更改时,useEffect将触发回调函数。

让我展示我的代码。我添加了评论以轻松解释正在发生的事情。在嵌套的Child组件上,我正在从父级中调用一个函数以从状态中删除一个项。这种情况就很好了,我正在将新状态传递给具有map函数的子组件,但是map函数不会更新。我觉得我没有正确使用useEffect()。

const Parent = (props) => {
    const [template_data, setTemplateData] = useState({});

    // called on an onChange somewhere in the Parent component.  Works fine. 
    const fetch = (e) => {
      ... 
      .then(response => {
          setTemplateData(JSON.parse(response.test_data))
      })
    }

    // Called in a nested child component
    // This is updating the state just fine.
    const removeGroupItem = (index, name ) => {
        let group = name.split('.')[1]
        const newState = template_data;
        if (index === -1) return;
        newState[group].splice(index, 1);
        setTemplateData(newState)
    }
    return (
        <DynamicForm template={template_data} removeGroupItem={(id, name) => removeGroupItem(id, name)}/>
    )
}

const DynamicForm = (props) => {
    const [ template_data, setTemplateData ] = useState({...props.template});

    // my understadning is if props change, fire callback setTemplateData(), correct? 
    useEffect(() => {
        setTemplateData(props.template)
    }, [props])

    return (
        Object.keys(template_data).map((section, index) => (
          // Passing Parent function removeGroupItem() to nested child
          <DynamicInputGroup removeGroupItem={props.removeGroupItem} {...section} key={index} />
        ))
    )
}

const DynamicInputGroup = (props) => {
    const [ state, setState ] = useState({...props});

    // Again, do I check if props from DynamicForm change fire state update? 
    useEffect(() => {
        setState(props)
    }, [props])

    return (
        <Fragment>
            // Mapping state
            {state.defaultValue.map((obj, id) => {
                return (
                  <Fragment key={id}>
                    // Mapping each object within the above map (needed for my case of response from fetch)
                      {Object.keys(obj).map((field, key) => {
                          let data = {
                              // blah blah defining some stuff
                          }
                          return (
                            <Field component={DynamicTextInput} {...data} key={data.name}/>
                          )
                      })}
                      // onClick triggers function in Parent component, I see the change in state on Parent, see the change on DynamicForm Props and State, and see the state change on this component, but no re render happens in above map.
                      {id >= 1 ? <span onClick={() => state.removeGroupItem(id, state.name)}>remove me</span> : ''}
                  </Fragment>
                )
            })}
        </Fragment>
    )
}

有什么想法吗?我很想学习,而不仅仅是一个答案。我是Hooks的新手。

编辑:我正在阅读此书,这就是为什么让我感到困惑的原因。 How to rerender component in useEffect Hook

0 个答案:

没有答案