每次我在data prop中获取新数据,但组件不重新渲染,直到我调用handlePanelSelection()
function StepPanel({ data, getTranslations }) {
const [panelsData, changePanel] = useState(data);
function handlePanelSelection(panelId) {
switch (panelId) {
case 8:
changePanel(getTranslations.NeeSubCategory);
break;
default:
changePanel(data);
break;
}
}
return (
<>
{panelsData.map(details => {
const imgsrc = requireContext('./' + details.image);
return (
<div key={details.id} className="block-list">
<div className="left-block">
<img src={imgsrc} alt="" />
</div>
<div className="right-block">
<h3>{details.title}</h3>
<p>{details.description}</p>
<label htmlFor="radio1" className="radio-btn">
<input
type="radio"
onClick={() => handlePanelSelection(details.id)}
name="radio1"
/>
<span></span>
</label>
</div>
</div>
);
})}
</>
);
}
但是当我像下面一样移除钩子时,
function StepPanel({ data, getTranslations }) {
return (
<>
{data.map(details => { ... })}
</>
)
}
我想实现一种功能,当我在数据道具中获取新数据时,该组件将被重新渲染,但是当我需要在内部进行重新渲染时,例如像我更改panelId = 8时,它也会被重新渲染,
上面的代码似乎会重新渲染,但是每次都使用相同的数据,即,虽然每次为数据道具提供新的更新值,但每次都不会更新panelData
答案 0 :(得分:3)
这是因为当您这样做时:
const [panelsData, changePanel] = useState(data);
您仅将data
道具用作panelsData
的初始值。当道具更改时,新数据将被忽略,因为panelsData
有其自己的状态(嗯,这是一个useState挂钩!)。
这就是为什么您必须显式调用changePanel
来更改状态的原因。 这就是整个想法!
如果您想观察data
道具并相应地更新状态,则可以使用带有useEffect
作为依赖项的data
钩子(这意味着它仅在{ {1}}的更改),例如:
data
祝你好运!
答案 1 :(得分:0)
您是否曾经尝试过使用useEffect处理组件的重新渲染:
function handlePanelSelection(panelId) {
switch (panelId) {
case 8:
changePanel(getTranslations.NeeSubCategory);
break;
default:
changePanel(data);
break;
}
}
useEffect(() => {
}, [panelsData]) // just pass panelsData into here
// Component will re-render when panelsData change.
答案 2 :(得分:0)
如果您替换代码的这一部分,是否可行?
// this block creates new function when re-render
// replace
function handlePanelSelection(panelId) {
switch (panelId) {
case 8:
changePanel(getTranslations.NeeSubCategory);
break;
default:
changePanel(data);
break;
}
}
// by
const handlePanelSelection = useCallback(()=> {
switch (panelId) {
case 8:
changePanel(getTranslations.NeeSubCategory);
break;
default:
changePanel(data);
break;
}
}, [data, getTranslations])