问题:组件渲染开始偏离实际状态
所需输出:组件渲染与状态匹配。
所以。由于这个问题相当复杂,我将对伪代码进行一个高级概述,然后我将展示代码。
我有一个主窗体,这个窗体有一个过滤器状态数组,可以在它们自己的组件中渲染。这些筛选器状态与表单是一对多关系。表单有许多筛选器状态。
form: {
filters: [
filter1,
filter2
]
}
假设你想从状态中删除一个项目,你可以在reduce(redux(中这样做
state.form.filters.filter(f => f.id != action.payload.id)
一切都很好。状态已更新。
比方说,如果你想呈现这种状态,你可以这样做:
// component code ommited, but say you get your form state from redux into the component
formState.filters.map(filter => <FilterComponent filter={filter}/>
一切都很好。你的过滤器被注入到组件中,每个人都很高兴
现在。这就是它很快变得奇怪的地方。
我的FilterComponent
上有一个按钮,上面写着删除。这个删除按钮转到reducer,运行代码从表单状态中删除过滤器(如上所述(,是的,它确实有效。状态得到更新,但是UI(组件数组(开始偏离状态。UI显示以前删除的状态,并且不显示应该持久化的状态(但在chrome上的redux选项卡中,状态是CORRECT…!(
UI的作用就好像状态数组是pop()
'd;无论如何删除状态,都将删除组件渲染中的最终状态。
现在,为代码。
// This takes a list of filters from the form state and loads them into individual form components
const Filters: NextPage<Filters> = () => {
const formState = useSelector((state: any) => state.form.formState)
// In the hope that state change will force reload components, but no avail
useEffect(() => {
console.log("something has been reloaded")
}, [formState])
return (
<>
{formState.form.map((filter, i) => {
return <FilterForm defaultState={filter} key={i} index={i} />
})}
</>
);
};
export default Filters;
这些单独状态的形式:请注意,这显然被编辑了很多,但包含了完整的逻辑
const FilterForm: NextPage<FilterFormProps> = ({ defaultState, index }) => {
const formState = useSelector((state: any) => state.form.formState)
// Local component state; there are multiple forms so the state should be localised
const [FilterState, setFilterState] = useState(defaultState)
const handleDelete = (e) => {
dispatch(deleteFilter(filterState.id))
}
const updateParentState = async () => {
dispatch(updateForm(filterState))
}
useEffect(() => {
updateParentState()
}, [filterState])
return (
<CloseButton position="absolute" right="0" top="25px" onClick={handleDelete} name={filterState.id} />
<Input
name="filter_value"
onChange={handleOnChange} // does standard jazz
value={filterState.filter_value} // standard jazz again
/>
)
}
现在发生的情况是:如果我单击删除,redux会更新正确的状态,但组件会显示已删除的状态输入。即,采取以下措施:
filter1: {filter_value: "one"}
filter2: {filter_value: "two"}
filter3: {filter_value: "three"}
这些过滤器以它们自己的形式呈现。
比如说,我在filter1上单击删除。
filter1将从redux中删除,但UI将显示两种形式:一种用于filter1,另一种用于filter 2。
从UI到状态的这种漂移让我很困惑。很明显,我做错了什么,有人能发现它是什么吗?!
所以,我解决了这个问题。
事实证明,并没有真正的解释为什么上面的行为会如此,但它确实保证了更好的实现。
问题如下:;redux状态与它被注入的渲染组件的本地状态相冲突。为什么会这样,则另当别论。不知怎的,在将redux状态注入组件并将其分配给本地状态时,这些状态有点混乱,并逐渐分离。
解决方案是摆脱局部状态(filterState
(,即updateParentState
函数调用,而是直接通过其所在的父状态更新局部状态。
新组件看起来如下:
const FilterForm: NextPage<FilterFormProps> = ({ state, index }) => {
const handleDelete = (e) => {
dispatch(deleteFilter(filterState.id))
}
const handleChange = (e) => {
dispatch(updateFormFilterState({ ...state, [e.target.name]: e.target.value }))
}
return (
<CloseButton position="absolute" right="0" top="25px" onClick={handleDelete} />
<Input
name="filter_value"
onChange={handleChange}
value={state.filter_value}
/>
)
}
希望这个答案能帮助到和我有同样问题的人。