[英]React not rerendering the component when prop changes
我有一個選項列表組件,它根據所選選項呈現一些子項。 當我在兩個選項中渲染相同的組件但使用不同的道具時會出現問題,因為在這種情況下,組件不會使用新道具重新渲染。
讓我澄清一下問題:我有一個選擇列表,我有一個 select 選項“A”,然后在選擇列表下方呈現一個文本組件,我在該文本字段中輸入“錯誤”,然后在選擇列表中輸入 select 選項“B”,然后其他文本字段組件消失,另一個文本字段組件在選項列表下方呈現。 最后一個組件應該被渲染為空,但問題是它包含單詞“error”。
這是重現錯誤的代碼的最小化版本:
import React from "react";
class TextField extends React.Component {
constructor(props) {
super(props);
this.state = { value: props.value };
}
_onChange = (event) => {
this.setState({ value: event.currentTarget.value });
};
_handleBlur = (event) => {
this.setState({ value: event.currentTarget.value.trim() });
};
render() {
const { value } = this.state;
return (
<div>
<label>TextField</label>
<input
type="text"
onChange={this._onChange}
onBlur={this._handleBlur}
value={value}
/>
</div>
);
}
}
class Picklist extends React.Component {
constructor(props) {
super(props);
this.state = { selectedOption: "" };
this.options = ["Blank", "A", "B"];
}
// eslint-disable-next-line consistent-return
_handleSelectorCallback = (newOption) => {
this.setState({ selectedOption: newOption.currentTarget.value });
};
_renderChildren(selectedOption) {
if (!selectedOption) {
return null;
}
if (selectedOption === "A") {
return <TextField value="optionA"/>;
}
if (selectedOption === "B") {
return <TextField value="optionB"/>;
}
}
_renderOptions() {
const { selectedOption } = this.state;
return this.options.map((option) => (
<option value={option} selected={selectedOption === option}>
{option}
</option>
));
}
render() {
const { selectedOption } = this.state;
return (
<React.Fragment>
<div>
<label>Demo of the Error!</label>
<select
onChange={this._handleSelectorCallback}
value={selectedOption}
>
{this._renderOptions()}
</select>
</div>
{this._renderChildren(selectedOption)}
</React.Fragment>
);
}
}
export default Picklist;
忽略組件的編寫有多糟糕,只是為了重現我遇到的錯誤。 知道為什么組件沒有用新值重新渲染嗎?
我認為正在發生的事情是,當您從一個<TextField>
切換到另一個時,React 試圖通過將不同的道具傳遞給同一個實例來提高效率。 你可以告訴 React 它們是不同的,應該通過添加一個鍵來重新渲染:
_renderChildren(selectedOption) {
if (!selectedOption) {
return null;
}
if (selectedOption === "A") {
return <TextField key="A" value="optionA" />;
}
if (selectedOption === "B") {
return <TextField key="B" value="optionB" />;
}
}
或者,您可以使您的TextField
成為受控組件,這意味着它沒有內部 state,並且 value/onChange fn 作為道具傳入。 我編輯了您的代碼框以遵循此模式: https://codesandbox.io/s/empty-wind-43jq4?file=/src/App.js
我試過你的沙盒。 您的TextField
組件不會被卸載,因此它的構造函數只被調用一次。 您所做的與該組件有關的每項更改都會轉到它的componentDidUpdate
掛鈎。
所以這就是你所缺少的:
componentDidUpdate() {
if (this.state.value !== this.props.value) {
this.setState({ value: this.props.value });
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.