Updating the state only renders the button (see attached video) instead entire component. Isn't React supposed to render the entire component the state belongs to?
export default function Edit({ className, attributes, setAttributes }) {
const [video, setVideo] = useState("3TgzifjO15g");
const addVideo = () => {
setVideo(attributes.videoId);
};
return (
<div {...useBlockProps()}>
<div className="wrapper">
<TextControl
label="YouTube video ID"
help="Algo parecido a: DyTCOwB0DVw"
className={className}
value={attributes.videoId}
onChange={(val) => setAttributes({ videoId: val })}
/>
<Button isPrimary onClick={addVideo}>
Añadir vídeo. añadido: {video}
</Button>
<Player controls>
<Youtube videoId={video} />
</Player>
</div>
</div>
);
}
Updating the state only renders the button (see attached video) instead entire component. Isn't React supposed to render the entire component the state belongs to?
https://youtube.com/shorts/FjcZE-sWh3c
export default function Edit({ className, attributes, setAttributes }) {
const [video, setVideo] = useState("3TgzifjO15g");
const addVideo = () => {
setVideo(attributes.videoId);
};
return (
<div {...useBlockProps()}>
<div className="wrapper">
<TextControl
label="YouTube video ID"
help="Algo parecido a: DyTCOwB0DVw"
className={className}
value={attributes.videoId}
onChange={(val) => setAttributes({ videoId: val })}
/>
<Button isPrimary onClick={addVideo}>
Añadir vídeo. añadido: {video}
</Button>
<Player controls>
<Youtube videoId={video} />
</Player>
</div>
</div>
);
}
This works. I'm not sure why, but separating the Player component in other component I can update the component from the button callback.
Just to explain the use of useState here: the videoId
attribute is saved in the comment delimiter block when saving the post. That is something that has already been achieved, it is not a problem. That I needed is a way to preview the video in a player inside the editor when it was chosen in the TextControl
component.
This player cannot be rendered with the Texcontrol
onChange
callback because it will try to update with each character typed. For that reason I have included a button that updates the player when the ID is already fully written.
export default function Edit({ className, attributes, setAttributes }) {
const [video, setVideo] = useState("");
const addVideo = () => {
setVideo(attributes.videoId);
};
const AgVideo = () => {
return (
<Player controls>
<Youtube videoId={video} />
</Player>
);
};
return (
<div {...useBlockProps()}>
<div>
<TextControl
label="YouTube video ID"
help="Algo parecido a: DyTCOwB0DVw"
className={className}
value={attributes.videoId}
onChange={(val) => setAttributes({ videoId: val })}
/>
<Button isPrimary onClick={addVideo}>
Añadir vídeo. añadido: {video}
</Button>
<AgVideo />
</div>
</div>
);
}
<Youtube videoId={attributes.videoId} />
instead. At the moment it's possible for the youtube player to show one video, but a different video gets saved because you didn't click the button to preview it. (useState
is not the source of your problem ) – Tom J Nowell ♦ Commented Jul 26, 2022 at 10:53<Youtube videoId={attributes.videoId} />
only updates the video after saving the post. – aitor Commented Jul 26, 2022 at 11:11setState
is never stored or saved. If you don't modify the attributes then WP will never know the post was modified and the update will not be saved. I would also use the attributes not the state to set your default video ID, and the attribute to set your state, but i do not believe you need to use state at all here – Tom J Nowell ♦ Commented Jul 26, 2022 at 16:52