Javascript React props.children在第一次状态更改后不会重新渲染

Javascript React props.children在第一次状态更改后不会重新渲染,javascript,reactjs,Javascript,Reactjs,我有以下问题,我似乎无法解决 Container.jsx const [selectedCardTypeList, setSelectedCardTypeList] = useState([]); const onDragEnd = result => { const {destination, source, draggableId} = result; if (!destination) { return; } if (des

我有以下问题,我似乎无法解决

Container.jsx


  const [selectedCardTypeList, setSelectedCardTypeList] = useState([]);

  const onDragEnd = result => {

    const {destination, source, draggableId} = result;
    if (!destination) {
      return;
    }

    if (destination.droppableId === source.droppableId &&
        destination.index === source.index
    ) {
      return;
    }

    let newInputIds = inputs;
    newInputIds.splice(source.index, 1);
    newInputIds.splice(destination.index, 0, draggableId);
    setSelectedCardTypeList(newInputIds);
  };

  return (
      <div>
        <DragDropContext onDragEnd={onDragEnd}>
          <DroppableWrapper selectedCardTypeList={selectedCardTypeList}>
            {selectedCardTypeList.map((v, index) =>
                  <CardContainer removeCardType={removeCardType} cardType={v} index={index}/>
            )}
          </DroppableWrapper>
        </DragDropContext>
      </div>
  )

const[selectedCardTypeList,setSelectedCardTypeList]=useState([]);
const onDragEnd=结果=>{
const{destination,source,draggableId}=result;
如果(!目的地){
返回;
}
if(destination.droppableId==source.droppableId&&
destination.index==source.index
) {
返回;
}
设newInputIds=输入;
newInputIds.splice(source.index,1);
newInputId.splice(destination.index,0,draggableId);
设置所选卡片类型列表(新输入项);
};
返回(
{selectedCardTypeList.map((v,索引)=>
)}
)
DropableWrapper.jsx

import {Droppable} from "react-beautiful-dnd";
import React from "react";

export const DroppableWrapper = ({children, selectedCardTypeList}) => {
  return (
      <>
      <Droppable droppableId="droppable" direction="horizontal">
        {(provided, snapshot) => (
            <div
                className={selectedCardTypeList.length ? 'container-horizontal' : 'container-vertical'}
                ref={provided.innerRef}
                {...provided.droppableProps}
            >
              {children}
              {provided.placeholder}
            </div>
            )}
      </Droppable>
        </>
)};

export default DroppableWrapper;
从“dnd”导入{dropable};
从“React”导入React;
导出常量DropPableRapper=({子项,selectedCardTypeList})=>{
返回(
{(已提供,快照)=>(
{儿童}
{提供的.占位符}
)}
)};
导出默认DropPableRapper;
如您所见,我省略了很多代码,这是一个虚拟示例,但基本上,如果我以声明方式将子元素传递给父元素(使用.map),子元素将只考虑第一个状态更改,尽管我可以在操作中确认状态正在更新,在呈现{children}时不会反映这一点

有什么想法吗?谢谢大家!


CardContainer没有什么问题,如果我不将Droppable out抽象为包装器,只需将其与它工作的容器一起保留。

您需要使用函数来设置状态。在onDragEnd的末尾:

    setSelectedCardTypeList(prevState => {
        var newState = [...prevState.slice(0, source.index), ...prevState.slice(source.index + 1)];
        return [...newState(0, destination.index), draggableId, ...newState(destination.index)];
    });

您需要使用函数来设置状态。在onDragEnd的末尾:

    setSelectedCardTypeList(prevState => {
        var newState = [...prevState.slice(0, source.index), ...prevState.slice(source.index + 1)];
        return [...newState(0, destination.index), draggableId, ...newState(destination.index)];
    });

向我们展示更新状态的位置如果数组的内容发生了更改,
useState
hook无法“查看”。你应该改用
useReducer
钩子。所以我省略了很多代码,我使用的是漂亮的DnD,状态在onDragEnd属性中更新。我可以确认状态正在正确更新,我将console.log-out它并使用React扩展进行检查。如果我将映射移动到子组件,一切正常,因此我只能假设在动态传递props.children.map函数创建的每个组件都必须具有唯一键,这就是React跟踪更改的方式,请尝试添加键={index}到地图中的子标记call@HermitCrab感谢您的输入,恐怕这是我尝试的第一件事,但没有乐趣。告诉我们您在哪里更新状态
useState
hook无法“查看”数组的内容是否已更改。你应该改用
useReducer
钩子。所以我省略了很多代码,我使用的是漂亮的DnD,状态在onDragEnd属性中更新。我可以确认状态正在正确更新,我将console.log-out它并使用React扩展进行检查。如果我将映射移动到子组件,一切正常,因此我只能假设在动态传递props.children.map函数创建的每个组件都必须具有唯一键,这就是React跟踪更改的方式,请尝试添加键={index}到地图中的子标记call@HermitCrab谢谢你的输入,恐怕这是我第一次尝试,但没有什么乐趣。我使用如下函数设置新状态:setSelectedCardTypeList(()=>{return[…newInputId];})。。。它成功了。你能告诉我上下文是因为异步操作吗?您将输入分配给newInputIds,然后对其进行修改。我猜react仍然将其视为相同的值。。。它成功了。你能告诉我上下文是因为异步操作吗?您将输入分配给newInputIds,然后对其进行修改。我猜react仍然将其视为相同的值。