Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Unable to display information after using React Routes with "Lifting state up"

I’m learning React Router from textbook and facing a problem when changing from Switch to Routes with the new function of Lifting State Up. I can’t display text after clicking the ‘News’ link. Here shows the code:

/* index.jsx */

    const rootElement = document.getElementById('root');
    const root = createRoot(rootElement);

    root.render(
    <HashRouter>

    <Routes>
      <Route path='/home' element={<Home />} />
      <Route path='/' element={<Home />} />
      <Route path='/about' element={<About />} />
      <Route path='/news' element={<News />} />
    </Routes>
    </HashRouter>,
    );

/* About.jsx */ <- good code

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const About = () => (
<div>
  <Menu />
  <h1>這裡是關於我們 This is about us.</h1>
</div>
);

export default About;

enter image description here

/* News.jsx */ <- Problem comes in.

const News = () => {
  const [news] = useState([
    { id: 1, name: 'News1', describe: 'A wins!' },
    { id: 2, name: 'News2', describe: 'B wins!' },
  ]);


  return (
    <div>

      <Menu />
      <Routes>
        <Route path='/news/*' element={<><p>hello!</p><NewsList 
news={news} /></>} />
        <Route path='newsReader/:id' element={<><NewsReader news ={news} /></>} />
      </Routes>

    </div>
  );
};

export default News;

enter image description here

It should be like this:

enter image description here

I believe the problem lies in <Route path> but can’t find the solution.

The code <NewsList> and <NewsReader> is here:

const NewsList = props =>  (
        <ul>
            {
                props.news.map(theNews => (
                    <li key = {theNews.id}>
                        <Link to = {`/news/newsReader/${theNews.id}`}> 
   {theNews.name}</Link>
                    </li>
                ))
            }
        </ul>
    );


    export default NewsList;


    const NewsReader = (props) => {
       const {id:targetNewsId} = useParams();
       const targetNews = props.news.find(theNews => (
        String(theNews.id) === String(targetNewsId)
       ));

        return(
            <div>
                <h1>你正在閱讀 You are now reading {targetNews.name}</h1>
                <p>{targetNews.describe}</p>
            </div>
        )
    }

export default NewsReader;

Thank you very much for your answer.

>Solution :

For nested routes, you need to follow the below approach

// index.js -> /news/*

const rootElement = document.getElementById('root');
const root = createRoot(rootElement);

root.render(
<HashRouter>

<Routes>
  <Route path='/home' element={<Home />} />
  <Route path='/' element={<Home />} />
  <Route path='/about' element={<About />} />
  <Route path='/news/*' element={<News />} /> // here you need to /*
</Routes>
</HashRouter>,
);

For the News.jsx you need to have relative path to /news like below

const News = () => {
  const [news] = useState([
    { id: 1, name: 'News1', describe: 'A wins!' },
    { id: 2, name: 'News2', describe: 'B wins!' },
  ]);


  return (
    <div>

      <Menu />
      <Routes>
        <Route path='/*' element={<><p>hello!</p><NewsList 
news={news} /></>} />
        <Route path='newsReader/:id' element={<><NewsReader news ={news} /></>} />
      </Routes>

    </div>
  );
};

export default News;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading