I'm trying to share user-entered form data with a component that shows a "preview" of the formatted content. Similar to StackOverflow showing the markdown preview below this text-entry box, however in my case the data comes from multiple text fields.
To sync the data, I'm using a context (which appears to be the correct approach based on my research) but my problem is that I'm not sure how to share multiple values.
I figured each form field could send data as part of an object that for the receiving component, might look like this:
{
firstname: (input from first name field component)
address: (input from address field component)
other: (input from other field component)
}
The receiving component can then just read this data {preview.firstname}
.
When setting the value after a user has updated the field, I use the spread operator to combine existing data into a new object.
However, I get the feeling this is a problematic way to do this. The linter complains that the preview
object is not in the useEffect
dependencies, but if I put it there, it creates an infinite render loop.
const [field] = useField('firstname');
const { preview, setPreview } = useContext(MyContext);
useEffect(() => {
setPreview({
...preview,
name: field.value
});
}, [field.value, setPreview]);
I guess I could create a different context for each form field but that will get verbose and I don't think that's the right solution either.
I'm still learning React/Contexts so I'm unsure what the "right" solution is. Do I use one context for each "state" value I want to share, or can I share a "state" object safely?
CodePudding user response:
You can use functional set state:
setPreview(ps=>({
...ps,
name: field.value
}));
No need for preview
as dependency anymore.