block editor - Basic use of useState

admin2025-01-08  7

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>
    );
}
Share Improve this question asked Jul 26, 2022 at 8:25 aitoraitor 7152 gold badges8 silver badges23 bronze badges 4
  • 2 I'm a little confused by your code, what's the reason you're using state? It would be much simpler if you eliminated the button completely, and used <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
  • 2 also I suspect what you actually wanted to do at first was set the state for the text control when changes happened, not the attribute, then set the attribute in the callback, not the other way around – Tom J Nowell Commented Jul 26, 2022 at 10:56
  • Sorry for the confusion. I am in an early stage of my learning and I am still very confused about the use of React in general and its application in Gutenberg. The reason for using useState is to update the Player component without having to save the post. Using <Youtube videoId={attributes.videoId} /> only updates the video after saving the post. – aitor Commented Jul 26, 2022 at 11:11
  • you want to prefer the attributes whenever possible, setState 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
Add a comment  | 

1 Answer 1

Reset to default 0

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>
    );
}
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736271029a1489.html

最新回复(0)