reactjs - state 用作组件中的 props,状态更改不会重新渲染组件
问题描述
如果状态改变,React 会重新渲染。那么为什么下面的情况不能重新渲染呢?
根据程序行为,我发现
- 当状态改变时,如果该状态直接在组件中使用,它将被重新渲染。
- 当 state 改变时,如果 state 被用作子组件中的 props,则不会重新渲染。
- 如何直接重新渲染该子组件?
以下程序来自我的代码并进行了一些修改。更新: 沙 箱这是我在沙箱中创建的代码,我尝试模拟我的真实情况
function List(props) {
const [fullListValue, setFullListValue] = useState([]); //store data which get from server
const [dropDrowList, setDropDrowList] = useState([]); //store data column value (e.g. data contain "fruit" column, this state will store "apple", "berry", "banana" etc.)
const setAllList = (data) => {
setFullListValue(data);
};
useEffect ( ()=> {
//axios call server, use setAllList(data) to save state
,[]}
//when fullListValue is updated,
useEffect(() => {
const dropDrowListCopy = [{ ['label']: 'ALL', ['value']: 'ALL' }];
//push all "fruit" data in dropDrowListCopy without duplicate
console.log(dropDrowListCopy); //this will show all dropdown I want, i.e. "ALL","apple", "berry", "banana"
setDropDrowList(dropDrowListCopy); //set to dropDrowList, and I expect this step will re-render the SelectionList component, however, it do not
}, [fullListValue]);
return (
<div>
<div>
{dropDrowList.length <= 1 ? (
'loading' //I add this to re-render the component, but I think this is not a good way to re-render the component
) : (
<SelectionList
itemList={dropDrowList}
/>
)}
</div>
</div>
);
}
解决方案
问题
在SecitonList
中,您将传递的道具存储到状态中,但不会在道具更改时更新状态,从而使您处于陈旧状态。出于这个原因,将 props 存储在本地组件状态中实际上是一种 React 反模式。
解决方案
道具改变时更新状态。
function SelectionList(props) {
const [listItem, setListItem] = useState(
props.itemList ? props.itemList : []
);
useEffect(() => {
setListItem(props.itemList);
},
[props.itemList]);
return (
<FormControl>
<Select
renderValue={
props.multiple ? (selected) => fieldDisplay(selected) : null
}
input={<Input />}
>
{listItem.map((item) => (
<MenuItem key={item.value} value={item}>
{props.multiple ? (
<Checkbox checked={selectedValue.indexOf(item) > -1} />
) : null}
<ListItemText primary={item.label} />
</MenuItem>
))}
</Select>
</FormControl>
);
}
解决方案——直接消耗道具
function SelectionList(props) {
return (
<FormControl>
<Select
renderValue={
props.multiple ? (selected) => fieldDisplay(selected) : null
}
input={<Input />}
>
{props.itemList.map((item) => (
<MenuItem key={item.value} value={item}>
{props.multiple ? (
<Checkbox checked={selectedValue.indexOf(item) > -1} />
) : null}
<ListItemText primary={item.label} />
</MenuItem>
))}
</Select>
</FormControl>
);
}
推荐阅读
- python - 取行中没有标签的数值,正则表达式
- python - InvalidArgumentError- 已明确分配给 /device:GPU:1 但可用设备为 [ /job:localhost/replica:0/task:0/device:CPU:0,
- python - 如何在 Flask SQLAlchemy 中的模型中存储列表
- java - 如何在 JPA2 中强制设置 @OneToMany 字段?
- ios - 更改状态变量/切换分段控制时调用函数
- unity3d - 轨迹预测的力量 Gold2d
- tcl - 如何在 tcl8.4.x 中合并两个列表
- oracle11g - IIB v10.19 通过 Windows 10 到 Oracle DB,JDBC 抛出错误
- android - 底部导航栏 - 未达到案例
- javascript - 在 React 的渲染方法中设置 CSS 变量是一种好习惯吗?