state is not being updated when using React Hooks

泄露秘密 提交于 2021-02-11 06:07:01

问题


I am currently playing around with the new React Hooks feature, and I have run into an issue where the state of a functional component is not being updated even though I believe I am doing everything correctly, another pair of eyes on this test app would be much appreciated.

import React, { useState, useEffect } from 'react';

const TodoList = () => {
  let updatedList = useTodoListState({ 
    title: "task3", completed: false 
  });
const renderList = () => {
  return (
    <div>
      {
        updatedList.map((item) => {
          <React.Fragment key={item.title}>
            <p>{item.title}</p>
          </React.Fragment>
        })
      }
    </div>
  )
}
return renderList();
}

function useTodoListState(state) {
  const [list, updateList] = useState([
    { title: "task1", completed: false },
    { title: "task2", completed: false }
  ]);
  useEffect(() => {
    updateList([...list, state]);
  })
  return list;
}

export default TodoList;

updateList in useTodoListState's useEffect function should be updating the list variable to hold three pieces of data, however, that is not the case.


回答1:


You have a few problems here:

  1. In renderList you are misusing React.Fragment. It should be used to wrap multiple DOM nodes so that the component only returns a single node. You are wrapping individual paragraph elements each in their own Fragment.
  2. Something needs to be returned on each iteration of a map. This means you need to use the return keyword. (See this question for more about arrow function syntax.)
  3. Your code will update infinitely because useEffect is updating its own hook's state. To remedy this, you need to include an array as a second argument in useEffect that will tell React to only use that effect if the given array changes.

Here's what it should all look like (with some reformatting):

import React, { useState, useEffect } from 'react';

const TodoList = () => {
  let updatedList = useTodoListState({
    title: "task3", completed: false
  });

  return (
    <React.Fragment> // #1: use React.Fragment to wrap multiple nodes
      {
        updatedList.map((item) => {
          return <p key={item.title}>{item.title}</p> // #2: return keyword inside map with braces
        })
      }
    </React.Fragment>
  )
}

function useTodoListState(state) {
  const [list, updateList] = useState([
    { title: "task1", completed: false },
    { title: "task2", completed: false }
  ]);

  useEffect(() => {
    updateList([...list, state]);
  }, [...list]) // #3: include a second argument to limit the effect

  return list;
}

export default TodoList;

Edit:
Although I have tested that the above code works, it would ultimately be best to rework the structure to remove updateList from useEffect or implement another variable to control updating.



来源:https://stackoverflow.com/questions/54974093/state-is-not-being-updated-when-using-react-hooks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!