繁体   English   中英

更改 state 后反应不渲染列表

[英]React not rendering list after the state is changed

我正在创建一个简单的跟踪器,用于记录所有已完成的活动。 这是我的第一个反应项目。 我创建了三个 state 一个用于存储所有项目(名称 state 是列表),一个用于待处理项目(名称 state is pending),一个用于完成项目(名称 state 已完成)。 这些项目有一个按钮,单击该按钮会将其标记为完成 state,反之亦然。 它正在完全渲染主列表的项目。 但对于其他两个,它没有渲染。 当我检查反应开发人员工具时,它工作正常,即它正在添加到待定列表或完成列表中。 但它不是在屏幕上编译它们。 列表中已经填满了项目。 为了以防万一,我添加了所有代码。

function Filters(props){
  const [completed, setCompleted] = useState([]);
  const [pending, setPending] = useState([]);
  const [state, setState] = useState("None");
  const [list,setList] = useState([]);

  function viewState(){
    setState("View-all");
  }

   //it is getting the clicked item id and marking it complete in main list
  function markComplete(id){
    list.map((items,index)=>{
      if(index===id){
        if(items.done===true)
          items.done = false;
        else{
          items.done=true;
        }
      }
    })
  }

//i am simply scanning the main list and the items which are pending will be added to this list. //this happens whenever the person click on pending button
 function pendingState(){
    setState("pending-all");
    setPending([]);
    list.map(items=>{
      if(items.done!==true){
        setPending(prev=>{
          return [...prev,items];
        })
      }
    })
  }

  function completedState(){
    setState("completed-all");
    setCompleted([]);
    list.map(items=>{
      if(items.done===true){
        setCompleted(prev=>{
          return [...prev,items];
        })
      }
    })
  }

 return (
    <div>
      <div className="input-section">
        <Note setList={setList} />
      </div>
      <button type="button" onClick={viewState} >View All</button>
      <button type="button" onClick={completedState}>Completed</button>
      <button type="button" onClick={pendingState}>Pending</button>
      <div>
        {
          (()=>{
            if(state==="View-all")
            {
              return (
                <div>
                  <h1>Working {completed}</h1>
                  {(list).map((items,index)=>
                    {
                    return (

                      <Excercise
                        key={index}
                        id={index}
                        title={items.name}
                        list={props.list}
                        setList={props.setList}
                        content={items.desp}
                        markComplete={markComplete}
                        />
                    )
                  })}
                </div>
              )
            }
            else if(state==="completed-all")
            {
              return (
                <div>
                {completed.map((items,index)=>{
                  <Excercise
                    key={index}
                    id={index}
                    title={items.name}
                    list={props.list}
                    setList={props.setList}
                    content={items.desp}
                    markComplete={markComplete}
                    />
                })}
                </div>
              )
            }
  })()
        }

      </div>


    </div>);
}



请帮忙。 谢谢你。

嗨@DREW function 代码:

  function markComplete(id){
    setList(lists=>{
      lists.map(item=>{
      return item.id===id ?{...item,done: !item.done} : (item);})
      }
      )
  }

当我使用它而不是

 const markComplete = (id) => {
    setList((list) =>
      list.map((item) =>
        item.id === id
          ? {
              ...item,
              done: !item.done
            }
          : item
      )
    );
  };

它显示,“无法读取未定义的属性(读取‘过滤器’)”两者并不相同。 如果不是,我做错了什么。 抱歉打扰了这么多次,我刚刚开始使用 React。

我认为你把事情复杂化了一点。 您只需要一个数组来存储练习,“待定”和“已完成”状态很容易从list state 和state过滤器 state 值中导出。

问题

  • markComplete回调正在改变list state。当更新list state 时,不仅需要新的数组引用,而且新元素 object 引用对于正在更新的元素也是必需的。
  • 使用较差的 boolean 比较来设置 boolean 值。 您可以切换 boolean 或将值设置为 boolean 表达式的结果。
  • 使用viewStatependingStatecompletedState处理程序来简单地设置过滤器值,然后在渲染时通过添加内联filter function 派生计算出的 state。
  • 使用 exercise id属性作为 React 键用于切换完成 ( done ) state 的属性。

解决方案

function Filters(props) {
  const [state, setState] = useState("None");
  const [list, setList] = useState([
    ...
  ]);

  function viewState() {
    setState("View-all");
  }

  function pendingState() {
    setState("pending-all");
  }

  function completedState() {
    setState("completed-all");
  }

  const markComplete = (id) => {
    setList((list) =>
      list.map((item) =>
        item.id === id
          ? {
              ...item,
              done: !item.done
            }
          : item
      )
    );
  };

  return (
    <div>
      <div className="input-section">
        <Note setList={setList} />
      </div>
      <button type="button" onClick={viewState}>
        View All
      </button>
      <button type="button" onClick={completedState}>
        Completed
      </button>
      <button type="button" onClick={pendingState}>
        Pending
      </button>
      <div>
        {list
          .filter((item) => {
            if (state === "pending-all") {
              return !item.done;
            } else if (state === "completed-all") {
              return item.done;
            }
            return true;
          })
          .map((item) => (
            <Excercise
              key={item.id}
              id={item.id}
              done={item.done}
              title={item.name}
              content={item.desp}
              markComplete={markComplete}
            />
          ))}
      </div>
    </div>
  );
}

在状态更改后编辑 react-not-rendering-list

尝试在useEffect中添加依赖

在这个 function 中,你正在改变一个 state,所以为了这样做你需要使用 setState function,在这种情况下,它将是 setList()。

 function markComplete(id){
    list.map((items,index)=>{
      if(index===id){
        if(items.done===true)
          items.done = false;
        else{
          items.done=true;
        }
      }
    })
  }

因此,实现此 function 的更好方法可能是,请记住,每次您需要更新 state 时,您不想直接更改 state,相反,您应该制作一个副本并将 state 设置为该副本

function markComplete(id){
  const newList = [...list];

  newList.map((items,index)=>{
      if(index===id){
        if(items.done===true)
          items.done = false;
        else{
          items.done=true;
        }
      }
  }
  setList(newList)
}

您的应用程序未更新的原因是因为当您的 state 更改反应时不会再次重新呈现它。

所以使用useEffect有很多钩子可以根据需要使用

尝试把这行代码

useEffect( ( ) => {
  
   console.log( 'Check console' );

}, [ dependency_here ] );

dependency_here尝试添加statecompletedpending一个一个地看结果。 您还可以添加多个依赖项,例如[ state, pending, etc.. ]

自己尝试一下,您会更快地理解它。

希望提示能帮到你!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM