谁能解释为啥这适用于类组件而不是功能组件?
Posted
技术标签:
【中文标题】谁能解释为啥这适用于类组件而不是功能组件?【英文标题】:Can anyone explain why this works with a class component but not a functional component?谁能解释为什么这适用于类组件而不是功能组件? 【发布时间】:2021-03-14 20:13:00 【问题描述】:基本上,我有几个按钮。我希望用户能够选择多个按钮。
我尝试使用功能组件并使用 useState 挂钩将按钮状态存储为对象。单击按钮时状态会相应更新,但按钮的道具不会更新。当 props.isActive 发生变化时,我尝试使用 useEffect 重新渲染组件,但这不起作用。
使用类组件,这完全符合预期。我只是想了解为什么会这样。如果有人能提供见解,我将不胜感激。谢谢。
功能组件
const View = (props) =>
var [buttons, setButtons] = useState([
name: "Small", isActive: false ,
name: "Large", isActive: false ,
]);
const handleClick = (index) =>
let tmp = buttons;
tmp[index].isActive = !tmp[index].isActive;
return setButtons(tmp);
;
return (
<div>
buttons.map((e, index) =>
return (
<MyButtonComponent
key=index
name=e.name
isActive=e.isActive
onClick=() => handleClick(index)
/>
);
)
</div>
);
;
类组件
class View extends Component
state =
btn: [
name: "Small", isActive: false ,
name: "Large", isActive: false ,
],
;
handleClick = (index) =>
let tmp = this.state.btn;
tmp[index].isActive = !tmp[index].isActive;
return this.setState( ...this.state, btn: tmp );
;
render()
return (
<div>
this.state.btn.map((e, index) =>
return (
<MyButtonComponent
key=index
name=e.name
isActive=e.isActive
onClick=() => this.handleClick(index)
/>
);
)
</div>
);
【问题讨论】:
【参考方案1】:您正在对旧数组进行变异,然后使用变异数组设置状态。无论您使用的是类组件还是函数组件,这在 react 中都不是一个好主意。类组件让你侥幸逃脱,但函数组件将之前的状态与之后的状态进行比较,发现它们是同一个数组,因此它跳过了渲染。
要解决此问题,您应该创建一个新状态而不是改变旧状态。改变这个:
let tmp = buttons;
tmp[index].isActive = !tmp[index].isActive;
return setButtons(tmp);
到这里:
// Create a copy of the array
let tmp = [...buttons];
// Also copy the item you want to change
tmp[index] =
...tmp[index],
active: !tmp[index].active
setState(tmp);
【讨论】:
啊哈,这很有道理。谢谢你。您的解决方案效果很好:)【参考方案2】:您正在更新引用并将相同的引用设置为 state(setButtons(tmp))
,其中 react thinks
, 数组由于浅比较而没有更改。您需要使用新的参考。像下面这样
let tmp = buttons; <-- problem is here, reference
tmp[index].isActive = !tmp[index].isActive;
return setButtons(tmp); <-- and updating same `reference`
const handleClick = (index) =>
buttons[index].isActive = !buttons[index].isActive;
return setButtons([...buttons]); <-- this will work
;
【讨论】:
感谢您的解释,我很感激。这也很好用!以上是关于谁能解释为啥这适用于类组件而不是功能组件?的主要内容,如果未能解决你的问题,请参考以下文章
是否有适用于类组件的 React Material-UI makeStyles() 函数的非挂钩替代方案