Страница React не загружает новый контент

Я пытаюсь перенаправить страницу декларативно.

Вот мой Header.js:

const Header = () => {  
    const [data, setData] = useState({ objects: [] });
    useEffect(async () => {
        const result = await axios.get(
            "http://example.com/api/v1/categories"
        );
        setData(result.data);
    }, []);

    return (
        <div>
            {courses.map( objects => (
                <Link to={`/cats/${objects.id}`}>{objects.title}</Link>
            ))}
        </div>
    );
};

export default Header;

Вот мой App.js

class App extends Component {
    render(){
        return (
            <Router>
                <Redirect exact from="/" to="/index" />
                <Route path = "/" component = {App}>
                    <Header/>
                    <Route path="/cats/:objectId" component={CoursePage} />
                </Route>
            </Router>
        );
    }
}
export default App;

Вот CoursePage.js:

const CoursesPage = (props) => {

    let { objectId } = useParams();


    const [data, setData] = useState({ courses: [] });

    useEffect(() => {
        (async () => {
            const result = await axios.get(
                "http://example.com/api/v1/cats/"+objectId
            ).catch(err => {
                console.error(err);
            });
            setData(result.data);
        })();
    }, []);


    return (
        <Fragment>
            {courses.title}
        </Fragment>
    );
};

export default CoursesPage;

В заголовке я нажимаю на ссылки. Он успешно перенаправляет на страницу курса. Но когда я снова нажимаю ссылку на другой курс, он не перезагружает компонент и не загружает новые данные. URL меняется, а страница нет.

Как я могу заставить страницу перезагрузить компонент?


person sundowatch    schedule 25.08.2020    source источник


Ответы (1)


Вы должны изменить массив зависимостей useEffect в CoursePage, чтобы он зависел от objectId, всякий раз, когда идентификатор объекта будет меняться, он будет перезапускать эффект.

const CoursesPage = (props) => {

let { objectId } = useParams();


const [data, setData] = useState({ courses: [] });

useEffect(() => {
    (async () => {
        setData({ courses: [] });    // add this line
        const result = await axios.get(
            "http://example.com/api/v1/cats/"+objectId
        ).catch(err => {
            console.error(err);
        });
        setData(result.data);
    })();
}, [objectId]);  // Update dependency array here


return (
    <Fragment>
        {courses.title}
    </Fragment>
);
}
 
export default CoursesPage;

Это сбросит предыдущие данные, прежде чем загружать новые, как только изменится идентификатор объекта.

Если вы хотите полностью перемонтировать компонент при изменении параметра в URL-адресе, вы можете добавить идентификатор в корневой элемент вашего компонента.

return (
<Fragment key={objectId}>
    {courses.title}
</Fragment>
);

Подробнее здесь...

person Atif Saddique    schedule 25.08.2020
comment
Если вы хотите полностью перемонтировать компонент реакции, вы можете сделать это следующим образом: -new-child-components-on-react-router-tra#answer-31816415" title="можно ли перемонтировать только новые дочерние компоненты на реагирующем маршрутизаторе tra%23answer 31816415"> stackoverflow.com/questions/31813512/ - person Atif Saddique; 25.08.2020
comment
Это немного сбивает с толку. Не могли бы вы привести пример моего кода? - person sundowatch; 25.08.2020
comment
Либо код, которым вы поделились, не содержит всей информации, либо я что-то здесь упускаю. в URL-адресе "http://example.com/api/v1/cats/"+propId есть propId Я полагаю, что это objectId, исходящий от useParams. Если это не так, то вам нужно сообщить мне, откуда берется этот параметр. Я также собираюсь немного обновить существующий ответ, чтобы вы могли его понять. - person Atif Saddique; 25.08.2020
comment
Я просто не мог понять, как я могу его перемонтировать - person sundowatch; 25.08.2020
comment
Я обновлю исходный ответ, включив в него подробности о перемонтировании компонентов. - person Atif Saddique; 25.08.2020
comment
Я обновил исходный ответ, включив в него то, как вы можете полностью перемонтировать компонент, если objectId изменится, вам просто нужно предоставить ключ к корневому элементу вашего компонента, как только ключ изменится, компонент будет вынужден перемонтироваться. - person Atif Saddique; 25.08.2020
comment
Давайте продолжим обсуждение в чате. - person Atif Saddique; 25.08.2020