简体   繁体   English

State 列表更改不会导致重新渲染 Next.js/React

[英]State list change not causing re-render Next.js/React

I've got the following state:我有以下 state:

const [places, setPlaces] = useState(false)
const [selectedPlaces, setSelectedPlaces] = useState([])

I asynchronously populate places by calling an API that returns an array of objects that looks something like:我通过调用返回一个对象数组的 API 来异步填充位置,该数组看起来像:

[
    {name: "Shop #1", id: 1},
    {name: "Shop #2", id: 2}
]

My goal is to render these objects, and have their ID to be added/removed from the selectedPlaces state.我的目标是渲染这些对象,并从selectedPlaces state 中添加/删除它们的 ID。

Render:使成为:

return (
  <div>
    <div>
      You have selected {selectedPlaces.length} total places
    </div>
    (places === false)
      ? <div>Loading...</div>
      : places.map(place => { // render places from the places state when loaded
          let [name, id] = [place.name, place.id]
          return <div onClick={() => {
            setSelectedPlaces(selected => {
              selected.push("dummy data to simplify")
              return selected
            })
          }}>{name}</div>
        })

  </div>
)

I've removed the key and added dummy data to make the movements simpler.我删除了密钥并添加了虚拟数据以使动作更简单。

The problem arises when clicking on a div, the "You have selected... total places" doesn't refresh until I force a re-render using fast refresh or through other methods (using browser/NextJS).单击 div 时会出现问题,“您已选择...总位置”不会刷新,直到我使用快速刷新或通过其他方法(使用浏览器/NextJS)强制重新渲染。 Is this correct behaviour?这是正确的行为吗? It's as-if the state isn't being changed, but a console.log on the setSelectedPlaces displays fresh data symbolizing it is being changed.好像 state 没有被更改,但setSelectedPlaces上的console.log显示新数据,表明它正在被更改。

I've tried:我试过了:

  • Creating a useEffect handler for the selectedPlaces state which would setAmtPlaces using the length of the selected places.selectedPlaces state 创建一个useEffect处理程序,它将使用所选地点的长度设置setAmtPlaces The same issue arises.出现同样的问题。
  • Searched/read-through multiple posts/GitHub issues like this and this搜索/阅读多个帖子/GitHub问题,例如thisthis
  • Replacing the list state with true/false in previous times I've encountered this issue, but I cannot use that approach with this problem since it's a dynamic amount of data being loaded.以前我遇到过这个问题,但我不能使用这种方法来解决这个问题,因为它是动态加载的数据量。
  • Add a {} wrapper for the ternary operator:为三元运算符添加一个{}包装器:

     { places === false? (...): (....) }
  • push mutates the state. push使 state 发生变异。 Use spread or concat in setSelectedPlacessetSelectedPlaces中使用 spread 或concat

     setSelectedPlaces(selected => selected.concat("abc") )
  • let [name, id] = [place.name, place.id] can be change to let { name, id } = place let [name, id] = [place.name, place.id]可以改为let { name, id } = place

Here's a snippet:这是一个片段:

 const { useState } = React; function App() { const [places, setPlaces] = useState([ { name: "Shop #1", id: 1 }, { name: "Shop #2", id: 2 } ]) const [selectedPlaces, setSelectedPlaces] = useState([]) const onPlaceClick = id => setSelectedPlaces(state => state.concat(id)) return ( <div> <div> You have selected {selectedPlaces.length} total places </div> { (places === false)? <div>Loading...</div>: places.map(({ id, name }) => <div onClick={_ => onPlaceClick(id)}>{name}</div> ) } <span>{selectedPlaces.join()}</span> </div> ) } ReactDOM.render( <App />, document.getElementById("react") );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> <div id="react"></div>

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

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