useEffect 在params改变时不会重新运行
useEffect does not re-run when the params changes
我的导航栏上有 6 个 link(家庭、世界、政治、商业、技术、体育),我只希望“部分”参数成为这些值之一。如果输入其他值的“节”,它会显示“找不到页面”的消息。
所有 6 个 link 都正常工作。单击导航栏上的另一个 link 时,useEffect 会重新运行。但是,如果我输入无效的节参数,它首先会显示“找不到页面”消息,
然后我在导航栏上单击 link,useEffect 没有重新运行并且应用程序崩溃了。
我不明白为什么 useEffect 没有重新运行,我确实指定了 props.match.params.section 作为它的依赖项。
const Headlines = (props) => {
useEffect(() => {
console.log(props.match.params.section);
props.getArticles(props.match.params.section === 'sports' ? 'sport' : props.match.params.section);
}, [props.match.params.section]);
if (props.match.params.section !== undefined &&
props.match.params.section !== 'world' &&
props.match.params.section !== 'politics' &&
props.match.params.section !== 'business' &&
props.match.params.section !== 'technology' &&
props.match.params.section !== 'sports') {
return (
<Container fluid>
<h1>The page cannot be found</h1>
</Container>
);
}
return (
props.news.loading ?
<Spinner/>
:
<Container fluid className={classes.headlines}>
{props.news.articles.map((article) => {
return <HeadlineItem key={article.id} article={article}/>
})}
</Container>
)
};
导航栏代码:
<Nav className="mr-auto">
<NavLink to="/"
exact
className={classes.link}
activeClassName={classes.selected}>Home</NavLink>
<NavLink to="/world"
className={classes.link}
activeClassName={classes.selected}>World</NavLink>
<NavLink to="/politics"
className={classes.link}
activeClassName={classes.selected}>Politics</NavLink>
<NavLink to="business"
className={classes.link}
activeClassName={classes.selected}>Business</NavLink>
<NavLink to="/technology"
className={classes.link}
activeClassName={classes.selected}>Technology</NavLink>
<NavLink to="/sports"
className={classes.link}
activeClassName={classes.selected}>Sports</NavLink>
</Nav>
App.js的代码:
function App() {
return (
<Provider store={store}>
<Router>
<NavigationBar/>
<Switch>
<Route exact path="/:section?" component={Headlines}/>
</Switch>
</Router>
</Provider>
);
}
import { hasIn } from "lodash";
const Headlines = (props) => {
const [state, setState] = React.useState({ status: "loading", data: [], currentSection: "" });
const filterList = ["world", "politics", "business", "technology", "sports"];
useEffect(() => {
if (hasIn(props, "match.params.section") &&
filterList.indexOf(props.match.params.section) > -1 &&
currentSection !== props.match.params.section
) {
props.getArticles(props.match.params.section).then((result) => {
if (result.length > 0) {
setState({ status: "found", data: result, currentSection: props.match.params.section });
} else {
setState({ status: "notfound", data: [], currentSection: "" });
}
}).catch((error) => {
console.log(error);
setState("notfound")
})
} else {
setState("notfound")
}
}, [props]);
switch (state.status) {
case "notfound":
return (
<Container fluid>
<h1>The page cannot be found</h1>
</Container>
);
case "found":
return <Container fluid className={classes.headlines}>
{data.map((article) => {
return <HeadlineItem key={article.id} article={article} />
})}
</Container>
default:
return <Spinner />
}
};
代码看起来不错。我认为在给无效部分参数时 props.getArticles() 似乎正在中断。这就是它中断的原因。如果您正在进行 http 调用,请添加 try catch 并检查。
props.getArticles(props.match.params.section === 'sports' ? 'sport' : props.match.params.section);
我已经根据您的代码片段创建了一个简单的工作版本,请查看下面的代码和框:
我做了什么?基本上,从您的代码片段中,eslint 已警告我此消息:
React Hook useEffect has a missing dependency: 'props'.
Either include it or remove the dependency array. However, 'props' will change when *any* prop changes,
so the preferred fix is to destructure the 'props' object outside of the useEffect call and refer to those specific props inside useEffect. (react-hooks/exhaustive-deps)
你应该首先像这样解构 useEffect
之外的 section
参数:
const [articles, setArticles] = useState([]);
const { section } = props.match.params;
useEffect(() => {
console.log(section);
setArticles([`${section} 1`, `${section} 2`]);
}, [section]);
if (
section !== undefined &&
section !== "world" &&
section !== "politics" &&
section !== "business" &&
section !== "technology" &&
section !== "sports"
) {
return <span>The page cannot be found</span>;
}
我的导航栏上有 6 个 link(家庭、世界、政治、商业、技术、体育),我只希望“部分”参数成为这些值之一。如果输入其他值的“节”,它会显示“找不到页面”的消息。
所有 6 个 link 都正常工作。单击导航栏上的另一个 link 时,useEffect 会重新运行。但是,如果我输入无效的节参数,它首先会显示“找不到页面”消息, 然后我在导航栏上单击 link,useEffect 没有重新运行并且应用程序崩溃了。
我不明白为什么 useEffect 没有重新运行,我确实指定了 props.match.params.section 作为它的依赖项。
const Headlines = (props) => {
useEffect(() => {
console.log(props.match.params.section);
props.getArticles(props.match.params.section === 'sports' ? 'sport' : props.match.params.section);
}, [props.match.params.section]);
if (props.match.params.section !== undefined &&
props.match.params.section !== 'world' &&
props.match.params.section !== 'politics' &&
props.match.params.section !== 'business' &&
props.match.params.section !== 'technology' &&
props.match.params.section !== 'sports') {
return (
<Container fluid>
<h1>The page cannot be found</h1>
</Container>
);
}
return (
props.news.loading ?
<Spinner/>
:
<Container fluid className={classes.headlines}>
{props.news.articles.map((article) => {
return <HeadlineItem key={article.id} article={article}/>
})}
</Container>
)
};
导航栏代码:
<Nav className="mr-auto">
<NavLink to="/"
exact
className={classes.link}
activeClassName={classes.selected}>Home</NavLink>
<NavLink to="/world"
className={classes.link}
activeClassName={classes.selected}>World</NavLink>
<NavLink to="/politics"
className={classes.link}
activeClassName={classes.selected}>Politics</NavLink>
<NavLink to="business"
className={classes.link}
activeClassName={classes.selected}>Business</NavLink>
<NavLink to="/technology"
className={classes.link}
activeClassName={classes.selected}>Technology</NavLink>
<NavLink to="/sports"
className={classes.link}
activeClassName={classes.selected}>Sports</NavLink>
</Nav>
App.js的代码:
function App() {
return (
<Provider store={store}>
<Router>
<NavigationBar/>
<Switch>
<Route exact path="/:section?" component={Headlines}/>
</Switch>
</Router>
</Provider>
);
}
import { hasIn } from "lodash";
const Headlines = (props) => {
const [state, setState] = React.useState({ status: "loading", data: [], currentSection: "" });
const filterList = ["world", "politics", "business", "technology", "sports"];
useEffect(() => {
if (hasIn(props, "match.params.section") &&
filterList.indexOf(props.match.params.section) > -1 &&
currentSection !== props.match.params.section
) {
props.getArticles(props.match.params.section).then((result) => {
if (result.length > 0) {
setState({ status: "found", data: result, currentSection: props.match.params.section });
} else {
setState({ status: "notfound", data: [], currentSection: "" });
}
}).catch((error) => {
console.log(error);
setState("notfound")
})
} else {
setState("notfound")
}
}, [props]);
switch (state.status) {
case "notfound":
return (
<Container fluid>
<h1>The page cannot be found</h1>
</Container>
);
case "found":
return <Container fluid className={classes.headlines}>
{data.map((article) => {
return <HeadlineItem key={article.id} article={article} />
})}
</Container>
default:
return <Spinner />
}
};
代码看起来不错。我认为在给无效部分参数时 props.getArticles() 似乎正在中断。这就是它中断的原因。如果您正在进行 http 调用,请添加 try catch 并检查。
props.getArticles(props.match.params.section === 'sports' ? 'sport' : props.match.params.section);
我已经根据您的代码片段创建了一个简单的工作版本,请查看下面的代码和框:
我做了什么?基本上,从您的代码片段中,eslint 已警告我此消息:
React Hook useEffect has a missing dependency: 'props'.
Either include it or remove the dependency array. However, 'props' will change when *any* prop changes,
so the preferred fix is to destructure the 'props' object outside of the useEffect call and refer to those specific props inside useEffect. (react-hooks/exhaustive-deps)
你应该首先像这样解构 useEffect
之外的 section
参数:
const [articles, setArticles] = useState([]);
const { section } = props.match.params;
useEffect(() => {
console.log(section);
setArticles([`${section} 1`, `${section} 2`]);
}, [section]);
if (
section !== undefined &&
section !== "world" &&
section !== "politics" &&
section !== "business" &&
section !== "technology" &&
section !== "sports"
) {
return <span>The page cannot be found</span>;
}