简体   繁体   中英

What's the best way (good practice !) to create a react component after an onClick trigger?

I just start learning by myself Reactjs and I'm facing a problem. I'm stuck and I would like to know how can I achieve to create a new <div> in the DOM when I click on a button.

In pure JS, I used an addEventListener on a button then I add / remove css style of my to display it (before that, the <div> was hidden) with classList . I presume that is not a best practice to implement it in Reactjs.

So, I would like to know how to do that.

Here is my first component.

const Welcome = () => {
    return (
        <div className="top">
          < Intro/>
          < InputUserName/>
          // Here, I need to build a new <div> only when I click on the following button (inside InputUserName)
        </div>
    )
};

Here is my second component with the button and the onCLick function.

const InputUserName = () => {
    const [username, setUsername] = useState('');
    return (
        <div className="usernameField">
            <div className="userField flex">
              <input
                type="text"
                name="username"
                className="userID"
                placeholder="Discogs' Username"
                value={username}
                autoComplete="off" autosuggest="off"
                onChange={(e) => setUsername(e.target.value)}>
                    {console.log(username)}
            </input>
                <span
                    className="usernameButton btn"
                    onClick={() => handleSubmitUserName(username)}>Send
                </span>
            </div>
        </div>
    )
};

And finally, here is my function called when I click on the SEND button

const handleSubmitUserName = (username) => {
    // Username field is empty !
    if (username === '') { 
        document.querySelector('.userID').style.border = "2px solid red";
    }
    // Username is !empty.
    // I need to build the following stuff inside the first component (the Welcome one). 
        return (
            <div className="hi">
                <p className="first">Hi <span class="pseudo">${username}</span>.</p>
                <p className="second">Let me find your next listening.</p>
            </div>
        )
};

There are a couple of ways to do it, but probably the simplest is to add a state member to Welcome which says whether to have the div or not, and have Welcome conditionally render the div based on that state member. You have Welcome pass InputUserName a function to call to update the state member, and have InputUserName call that function appropriately.

Here is what you need to do

const Welcome = () => {
  const [toggle, setToggle] = useState(false);
  const handleClick = () => setToggle((v) => !v);
  return (
    <div className="top">
      <button onClick={handleClick}>toggle the div</button>
      <Intro />
      <InputUserName />
      {toggle && <div>this would be visible when toggle is true</div>}
    </div>
  );
};

Basically you're looking to pass a value from a child component to a parent component. Here's one way of doing it.

We want to notify the "Welcome" component when the username has been submitted from the "InputUserName" component, so we're going to make an "onUsernameSubmitted" function.

const Welcome = () => {
   
   const [username, setUsername] = useState("");
   const [showMyDiv, setShowMyDiv] = useState(false);
   const handleUsernameSubmitted = (username) => {
      setUsername(username);
      setShowMyDiv(true);

   }

    return (
        <div className="top">
          < Intro/>
          < InputUserName onUsernameSubmitted={(username) => handleUsernameSubmitted} />
          {showMyDiv && <div>Your custom div will appear here</div>}
        </div>
    )
};

Then in this line const InputUserName = (props) => { notice that I've just added the "props" argument. Then in your handle function inside this component, call props.onUsernameSubmitted(username)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM