在 react/redux(使用工具包)中:
我有组件重新渲染 - 在 redux 操作上触发。 作用于不同的切片;
所以我的DOM结构如下
<DataWindow>
<DataSelector />
<DataIncoming />
<DataCardContainer />
</DataWindow>
Selector 接收并渲染一个通过点击传入的项目设置的道具; 但是 - 单击传入的项目会导致“DataCardContainer”重新呈现;
DataWindow 只不过是上面的 jsx
DataSelector 获取“逻辑”切片 - 并获取“dataSelector”属性并显示它;
function DataSelector(props){
const logic = useSelector(LOGIC);
return(
<div className="DataSelector">
selector {logic.dataSelector}
</div>
)
}
DataIncomming 是一个列表显示;
function DataIncoming(props){
const dispatch = useDispatch();
const incomingData = useSelector(selectNoData); //from jobs
const incoming = incomingData.map(x=><div key ={x.jID} className="incDataCard" onClick={()=>dispatch(setDataSelector(x.jID))}>{x.JobNum} {x.JobName} </div>)
return(
<div className="DataIncoming">
incoming {incoming}
</div>
)
}
function DataCardContainer(){
const madeData = useSelector(selectMadeData); //from the slice 'data'
const jobData = useSelector(selectJobs); // from the slice 'jobs'
const dataCards = madeData.map(x=>{
const foundJob = jobData.find(y=>y.jID === x.attachedJID);
console.log(foundJob,"founjob"); //this logs when i click on any of the 'incDataCard' rendered in DataIncoming
return(<DataCard key={x.DataKey} props={x} jobInfo={foundJob} />)})
return(
<div className="DataCardContainer">
{dataCards}
</div>
)
}
它使用作业选择器 (selectNoData) 并将它们显示在列表中 - 您可以单击该列表,从逻辑切片运行以下调度;
setDataSelector:(state,action)=>{
state.dataSelector=action.payload;
console.log("yay, setDataSelector");
return state;
}
让我困惑的是 DataCardContainer 和 DataWindow 根本不接触逻辑切片 -
所以我的问题是:为什么组件 DataCardContainer 在每次来自 DataIncoming 的分派时都重新渲染
答案 0 :(得分:2)
useSelector() 如果它产生的值已经改变,将导致重新渲染。当返回一个对象时,请注意除非它是相同的对象,否则即使对象属性相同,组件也会重新渲染。您可以通过始终返回相同的对象来解决此问题。
在您的情况下,仅选择所需状态的最简单方法是告诉 useSelector 进行浅等比较而不是引用相等比较。 useSelector 接受一个比较器函数作为第二个参数:
import { shallowEqual, useSelector } from 'react-redux'
const user = useSelector(
({user}) => ({
id: user.id
name: user.name
lastName: user.lastName
}),
shallowEqual
);