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

Time:07-05

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

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.

CodePudding user response:

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;
  • Related