Replies: 3 comments 5 replies
-
Next won't render the page until |
Beta Was this translation helpful? Give feedback.
-
@rafaelalmeidatk It took me one day to isolate the problem. Here is a code sandbox: https://codesandbox.io/s/small-leftpad-dsofl?file=/pages/index.js You will see that if you SSR /?user=1 or /?user=2, both work well. However, if you CSR either by clicking on the links above the home page, the result of the last SSR sticks and the link clicks do not change the value (you can see that the client has actually fetched the correct data from the getInitialProps via the console.log on your browser). Now, if you uncomment the useEffect clause, things work even in CSR mode. My question: Is this expected? What's the best way to achieve what I want to achieve? Is useEffect the best solution? This should be a common pattern. Thanks |
Beta Was this translation helpful? Give feedback.
-
I discussed about this problem with some folks at Reactiflux and these are the solutions I recommend: 1) Fully controlled componentThis solutions isn't always viable. Basically you don't control the state inside your page, you use the URL as your "state", so instead of having a copy of the user state in your page, you will always read from the props: const User = (props) => {
return (
<>
<Link href="/">
<a>User 1</a>
</Link>
<Link href="/?user=2">
<a>User 2</a>
</Link>
<h1>Current User</h1>
<div>{props.user.name}</div>
</>
);
}; This solution is more useful for things like wizard forms pages. 2) Using derived state from the propsThis a more common pattern, you receive the user data and want to let the user change it in your page, but if the user navigates to the page of another user, then the page has to reset to show the data of the new user. This solution is based on the example from the React docs of implementing const User = (props) => {
const [user, setUser] = useState(props.user);
const [prevUser, setPrevUser] = useState(props.user);
// Here I utilized the ID to keep the comparison cheap,
// if you don't have an unique identifier you would have
// to use something like lodash#isEqual
if (props.user.id !== prevUser.id) {
setUser(props.user);
setPrevUser(props.user);
}
return (
<>
<Link href="/">
<a>User 1</a>
</Link>
<Link href="/?user=2">
<a>User 2</a>
</Link>
<h1>Current User</h1>
<div>{user.name}</div>
</>
);
}; 3) Uncontrolled with a keyAn alternative to solution 2 is to move your logic to a component bellow, and render this component with a key that equals to the user ID: const User = (props) => {
return <UserContent key={props.user.id} initialUser={props.user} />;
};
const UserContent = (props) => {
const [user, setUser] = useState(props.initialUser);
return (
<>
<Link href="/">
<a>User 1</a>
</Link>
<Link href="/?user=2">
<a>User 2</a>
</Link>
<h1>Current User</h1>
<div>{user.name}</div>
</>
);
}; With this solution, everytime you change a page, the value of
|
Beta Was this translation helpful? Give feedback.
-
Can you please tell me what is the best way to update state after getInitialProps?
I have a page like this:
My Problem: When I fetch the data from the getInitialProps, it is not reflected on patient. Because by the time I get the fetch to respond, my page has already displayed empty data.
My solution: I added a useEffect inside my Page like this and now it works. Is this a hack? Is there a better way to do this?
Beta Was this translation helpful? Give feedback.
All reactions