问题
I'd like to randomly generate the id
property of form inputs, to prevent them from potentially conflicting with other inputs with the same id
. This could happen if I have two login forms on the same page, each with an email
field. The reason I want/need to set the id
property is so that I can set the for
property on the label
corresponding to that input. The problem is that this randomly generated id is different on the server and the client, and so next.js throws an error. Here's some code:
function uniqueId() {
let first = (Math.random() * 46656) | 0
let second = (Math.random() * 46656) | 0
first = ('000' + first.toString(36)).slice(-3)
second = ('000' + second.toString(36)).slice(-3)
return first + second
}
const Login = () => {
const [emailId] = useState(uniqueId())
return (
<form>
<label htmlFor={emailId}>Email</label>
<input id={emailId} name='email' type='email' />
</form>
)
}
This is the error I get:
Warning: Prop 'htmlFor' did not match. Server: "email-txdmls" Client: "email-htte8e"
Any idea how to generate a random id that's consistent on the server/client? Or maybe a different way of doing it without random ids?
回答1:
I found a workaround to this. I'm not sure if it's a great solution (see explanation below). Seems like a lot of trouble just to essentially suppress a warning message. Still very curious to hear alternate solutions. Honestly even a way to tell next.js to ignore the difference and not issue a warning would work fine (it doesn't matter that the ids differ on SSR and client).
So what I did is generate the id in a useEffect
hook. The problem is that initial server-side rendered HTML doesn't have an id
on the input. It's not until all the JS is processed that it gets an id. Not ideal.
const Login = () => {
const [emailId, setEmailId] = useState(null)
useEffect(() => {
setEmailId(uniqueId())
}, [])
return (
<form>
<label htmlFor={emailId}>Email</label>
<input id={emailId} name='email' type='email' />
</form>
)
}
来源:https://stackoverflow.com/questions/59976409/next-js-using-random-properties-without-triggering-did-not-match-on-server-cli