如何强制 React(使用钩子的功能组件)在 props 更改时从头开始创建新组件?
How to force React (functional component using hooks) to create a new component from scratch on props change?
TLDR
有没有办法强制 React 从头开始重新创建组件(使用钩子的功能组件),而不是在 prop
更改时重新渲染它?
编辑
关键属性有效。我遇到的问题是由于我正在执行的状态更新序列。第一次更新试图立即呈现需要完成最后一次更新的组件。
我正在开发一个名为 <AddProductWidget>
的组件,它将获得有关产品的以下 props
信息并需要显示其详细信息。它属于一个带有搜索栏的页面,您可以填写 productID 并从云功能中获取产品详细信息。
渲染成这样:
<AddProductWidget
userImages={props.productDetails.userImages} // Array of strings (urls)
title={props.productDetails.title}
stars={props.productDetails.stars}
/>
AddProductWidget.js
它呈现一个 <UserImages>
组件,让用户在保存到数据库之前点击一些图像到 select。所以它需要 state
到 'remember' 用户点击了哪些图像。
function AddProductWidget(props) {
const [userImagesSelected, setUserImagesSelected] = useState(
() => {
if (props.userImages && props.userImages > 0) {
return new Array(props.userImages.length).fill(false);
}
return null;
}
);
// IT renders the <UserImages> component
// The code here is simplified
return(
<UserImages
userImages={props.userImages}
userImagesSelected={userImagesSelected}
setUserImagesSelected={setUserImagesSelected}
/>
);
}
该数组 userImagesSelected
的初始状态应与 userImages
数组的长度相同,并填充 false
个值,一旦用户开始点击图像。如果产品没有用户图片,props.userImages
将是 null
,userImagesSelected
也应该是 null
。
当我加载第一个产品时,一切都按预期工作。不管有没有图,都显示正确
问题:
问题是当我加载一个包含零个图像的产品时,例如,随后我加载另一个包含 5 个图像的产品。基本上 AddProductWidget
的 props
会改变(因为它收到了一个新产品),但是因为 React 似乎试图使用相同的组件实例,所以我得到一个错误,因为我的 UserImages
组件将尝试呈现 selected 图像信息,但 userImagesSelected
的状态仍将是 null
,因为上一个产品没有图像。
当我使用 类 时,我可以强制 React 使用 key
属性重新创建一个组件实例,但这似乎不适用于钩子,因为以下代码没有'解决我的问题:
<AddProductWidget
key={productID}
userImages={props.productDetails.userImages} // Array of strings (urls)
title={props.productDetails.title}
stars={props.productDetails.stars}
/>
问题
有没有办法强制 React 从头开始重新创建组件(使用钩子的功能组件),而不是在 prop
更改时重新渲染它?
额外
A 找到了绕过它的方法,但它似乎有点老套,即使它在 React 文档中。它基本上使用状态来检测 props
何时更改并在渲染期间调用 setState()
。我希望从头开始重新创建我的组件。
不确定您是如何决定另一个 key
不会重新安装组件的,但它应该这样做(您确定密钥已更改?)
这里有一个 运行 例子来展示这个
function Test() {
React.useEffect(() => {
console.log('Test was mounted');
return () => {
console.log('Test was un-mounted');
};
}, []);
return "hi there, I'm Test";
}
function App() {
const [val, setVal] = React.useState("Change me...");
return (
<div className="App">
<input value={val} onChange={e => setVal(e.target.value)} />
<br />
<Test key={val} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />
TLDR
有没有办法强制 React 从头开始重新创建组件(使用钩子的功能组件),而不是在 prop
更改时重新渲染它?
编辑
关键属性有效。我遇到的问题是由于我正在执行的状态更新序列。第一次更新试图立即呈现需要完成最后一次更新的组件。
我正在开发一个名为 <AddProductWidget>
的组件,它将获得有关产品的以下 props
信息并需要显示其详细信息。它属于一个带有搜索栏的页面,您可以填写 productID 并从云功能中获取产品详细信息。
渲染成这样:
<AddProductWidget
userImages={props.productDetails.userImages} // Array of strings (urls)
title={props.productDetails.title}
stars={props.productDetails.stars}
/>
AddProductWidget.js
它呈现一个 <UserImages>
组件,让用户在保存到数据库之前点击一些图像到 select。所以它需要 state
到 'remember' 用户点击了哪些图像。
function AddProductWidget(props) {
const [userImagesSelected, setUserImagesSelected] = useState(
() => {
if (props.userImages && props.userImages > 0) {
return new Array(props.userImages.length).fill(false);
}
return null;
}
);
// IT renders the <UserImages> component
// The code here is simplified
return(
<UserImages
userImages={props.userImages}
userImagesSelected={userImagesSelected}
setUserImagesSelected={setUserImagesSelected}
/>
);
}
该数组 userImagesSelected
的初始状态应与 userImages
数组的长度相同,并填充 false
个值,一旦用户开始点击图像。如果产品没有用户图片,props.userImages
将是 null
,userImagesSelected
也应该是 null
。
当我加载第一个产品时,一切都按预期工作。不管有没有图,都显示正确
问题:
问题是当我加载一个包含零个图像的产品时,例如,随后我加载另一个包含 5 个图像的产品。基本上 AddProductWidget
的 props
会改变(因为它收到了一个新产品),但是因为 React 似乎试图使用相同的组件实例,所以我得到一个错误,因为我的 UserImages
组件将尝试呈现 selected 图像信息,但 userImagesSelected
的状态仍将是 null
,因为上一个产品没有图像。
当我使用 类 时,我可以强制 React 使用 key
属性重新创建一个组件实例,但这似乎不适用于钩子,因为以下代码没有'解决我的问题:
<AddProductWidget
key={productID}
userImages={props.productDetails.userImages} // Array of strings (urls)
title={props.productDetails.title}
stars={props.productDetails.stars}
/>
问题
有没有办法强制 React 从头开始重新创建组件(使用钩子的功能组件),而不是在 prop
更改时重新渲染它?
额外
A 找到了绕过它的方法,但它似乎有点老套,即使它在 React 文档中。它基本上使用状态来检测 props
何时更改并在渲染期间调用 setState()
。我希望从头开始重新创建我的组件。
不确定您是如何决定另一个 key
不会重新安装组件的,但它应该这样做(您确定密钥已更改?)
这里有一个 运行 例子来展示这个
function Test() {
React.useEffect(() => {
console.log('Test was mounted');
return () => {
console.log('Test was un-mounted');
};
}, []);
return "hi there, I'm Test";
}
function App() {
const [val, setVal] = React.useState("Change me...");
return (
<div className="App">
<input value={val} onChange={e => setVal(e.target.value)} />
<br />
<Test key={val} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />