useEffect не запускается повторно при изменении параметров - PullRequest
0 голосов
/ 21 июня 2020

У меня есть 6 ссылок (дом, мир, политика, бизнес, технологии, спорт) на моей панели навигации, и я хочу, чтобы параметр «section» был одним из этих значений. Если введено другое значение «раздела», будет отображаться сообщение «страница не найдена».

Все 6 ссылок работают правильно. useEffect запускается повторно при нажатии другой ссылки на панели навигации. Однако, если я ввожу недопустимый параметр раздела, сначала отображается сообщение «страница не может быть найдена», затем я нажимаю ссылку на панели навигации, 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>

Код приложения. js:

function App() {
    return (
        <Provider store={store}>
            <Router>
                <NavigationBar/>
                <Switch>
                    <Route exact path="/:section?" component={Headlines}/>
                </Switch>
            </Router>
        </Provider>
    );
}

Ответы [ 3 ]

1 голос
/ 21 июня 2020

Я создал простую рабочую версию на основе ваших фрагментов, пожалуйста, посмотрите на коды ниже:

Простая рабочая версия

Что я сделал? По сути, из вашего фрагмента 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)

Вы должны сначала деструктурировать параметр section за пределами useEffect следующим образом:

 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>;
  }
1 голос
/ 21 июня 2020
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 />
  }

};
0 голосов
/ 21 июня 2020

Код выглядит нормально. Я думаю, что при указании недопустимого раздела param props.getArticles () кажется, что он ломается. Вот почему он ломается. Если вы выполняете http-вызов, добавьте try catch и check.

 props.getArticles(props.match.params.section === 'sports' ? 'sport' : props.match.params.section);
...