我有组件
import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
const data = {
"1": ["1a", "1b"],
"2": ["2a"]
};
const slugs = {
"1a": { text: "Lorem" },
"1b": { text: "ipsum" },
"2a": { text: "..." }
};
const ExamplePage: React.FC = () => {
const { id } = useParams<{ id: string }>();
const [index, setIndex] = useState(0);
useEffect(() => {
setIndex(0);
}, [id]);
console.log("state", {
id,
index
});
const slug = data[id][index];
const text = slugs[slug].text;
function onPrev(): void {
if (index <= 0) {
return;
}
setIndex((index) => index - 1);
}
function onNext(): void {
if (index >= data[id].length - 1) {
return;
}
setIndex((index) => index + 1);
}
return (
<div>
<button onClick={onPrev}>Prev</button>
<span>{text}</span>
<button onClick={onNext}>Next</button>
</div>
);
};
export default ExamplePage;
并为此路由:
<Route path="/:id" component={ExamplePage} />
实时版本:https://codesandbox.io/s/react-hooks-ewl4d
在以下情况下,此代码存在错误:
/1
网址上/2
网址的链接在这种情况下,id
将是"2"
,index
将是1
,但没有data["2"][1]
。
您会看到useEffect
在这种情况下无济于事,因为useEffect
不会停止当前的函数调用。
我的问题是:如何确保这种状态始终正确?
我知道我可以编写const text = slugs[slug]?.text;
并解决了我的错误,但是仍然有一段时间,组件处于错误状态。我想知道是否是防止这种错误状态的方法。
在React类组件中,此问题可以通过getDerivedStateFromProps
解决-您可以在https://codesandbox.io/s/react-hooks-solve-in-react-component-xo43g上实时观看
答案 0 :(得分:0)
useEffect
将异步运行,因此您尝试在更新索引之前设置slug
和text
。
您可以将slug
和text
置于状态,然后在useEffect
或index
更改时使用另一个id
更新它们:
const { id } = useParams();
const [index, setIndex] = useState(0);
const [slug, setSlug] = useState();
const [text, setText] = useState();
useEffect(() => {
setIndex(0);
}, [id]);
useEffect(() => {
const newSlug = data[id][index];
if (!newSlug) return; // If id changes but index has not updated yet
setSlug(newSlug);
setText(slugs[newSlug].text);
}, [id, index]);