1

I'm trying to redirect page declaratively.

Here is my 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;

Here is my 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;

Here is the 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;

On Header I click to links. It redirects to course page successfully. But when I click again another course link, it doesn't reload the component and it doesn't load the new data. The URL changes, but page is not.

How can I force the page to reload the component?

sundowatch
  • 3,012
  • 3
  • 38
  • 66

1 Answers1

1

You should change the dependency array of useEffect in CoursePage to depend on objectId, whenever object id will change, it will rerun the effect.

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;

This will reset the previous data before to load new one as soon as object id changes.

If you want to remount component completely on param change in url, then you can add an id to your component root element.

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

More Info here...

  • If you want to completely remount the react component, then you can do it like this : https://stackoverflow.com/questions/31813512/is-it-possible-to-only-remount-only-the-new-child-components-on-react-router-tra#answer-31816415 – Atif Saddique Aug 25 '20 at 12:30
  • It's a little bit confusing. Could you please give example on my code? – sundowatch Aug 25 '20 at 12:36
  • Either the code you shared doesn't contain all information or I am missing something here. there is `propId` in url `"http://example.com/api/v1/cats/"+propId` I suppose this is `objectId`, coming from `useParams`. If its not, then you need to let me know where this parameter is coming from. I am going to update the existing answer a bit as well, so that you might be able to understand it. – Atif Saddique Aug 25 '20 at 12:45
  • I just couldn't understand how can I remount it – sundowatch Aug 25 '20 at 12:54
  • I will update the original answer to include details for component remount. – Atif Saddique Aug 25 '20 at 12:58
  • I have updated the original answer to include how you can remount the component entirely if the objectId change, you just need to provide key to your component root element, as soon as the key changes, the component will be forced to remount. – Atif Saddique Aug 25 '20 at 13:03
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/220430/discussion-between-atif-saddique-and-sundowatch). – Atif Saddique Aug 25 '20 at 13:13