I'm new to React. I have written a simple React application using Semantic UI, with two menu items, each corresponding to a specific page. I'm not sure how to make each page have its own state, and remember it when navigating the menu.
In index.js:
ReactDOM.render(
<Main />,
document.getElementById('root')
);
In Main.jsx:
export default class Main extends Component {
state = {
activePageId: 1
};
handleSelectPage = (e, { id: selectedPageId }) => {
this.setState({ activePageId: selectedPageId })
}
getActivePage() {
return (
<Page id={this.state.activePageId} />
)
}
render () {
return (
<Grid divided padded >
<Grid.Column width={2}>
<Menu vertical inverted pointing fluid>
<Menu.Item
id={1}
name='Page 1'
active={this.state.activePageId === 1}
onClick={this.handleSelectPage}
key={1}
/>
<Menu.Item
id={2}
name='Page 2'
active={this.state.activePageId === 2}
onClick={this.handleSelectPage}
key={2}
/>
</Menu>
</Grid.Column>
<Grid.Column width={14}>
{this.getActivePage()}
</Grid.Column>
</Grid>
);
}
}
Finally, in Page.jsx:
export default class Page extends Component {
state = {
counter: 0
};
increaseCounter = (e) => {
this.setState({ counter: this.state.counter + 1 });
}
render () {
return (
<React.Fragment>
<Header>Page {this.props.id}</Header>
{this.state.counter}
<Button primary content='+' onClick={this.increaseCounter}/>
</React.Fragment>
);
}
}
What I can't figure out:
The page id
is passed in the props when creating a Page
component in getActivePage()
. So, that changes every time I navigate the menu. However, the counter
is in the state of the Page
. That does not change as I navigate the menu. Am I correct to assume there is only one instance of a Page
, which is re-rendered when the props (in this case id
) change?
It seems like the only way to have a separate counter for each page is to have some sort global state (in a global object) and read from that when rendering a Page
. This would mean, however, that I need to call this.forceUpdate
inside Page.increaseCounter
to re-render the page without re-clicking the menu item. Is that the React way to go?
I'm also thinking about using routing. But, from my preliminary experiments, it seems that, compared to the current scenario, a new Page
would be created for each route (is this right?) with its own state. However, that state gets wiped out when navigating between routes, so I still need to keep a global state object and use forceUpdates
or so. Any ideas here?
Thanks!
You have to set the counter state inside your Main.jsx component, and then pass the counter state as props to Page.jsx. I recommend you to use functional components and useState hook. Here you can see an example https://codesandbox.io/s/recursing-bardeen-8w58z?file=/src/App.js