0

I am trying to have the SigninForm pass the email back to the component that called it (App). Then when email is updated App should re-render. I tried to create the structure given in an earlier question. However I could not get the App component to update and display the email in my React code.

TLDR: Why isnt the Email displaying on the snippet when I click the button?

function App() { const [email, setEmail] = React.useState(); return ( <div> EMAIL: {email} <br></br> <SigninForm setEmail={setEmail}/> </div> ) } function SigninForm() { const [email, setEmail] = React.useState() var credsSubmit = (event) => { event.preventDefault(); setEmail('[email protected]') } return ( <div> <form onSubmit={credsSubmit}> <input type='submit' /> </form> </div> ) } ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script> <div id="root"></div>

9
  • May you fix the syntax errors in the example? Commented Feb 4, 2021 at 21:21
  • Also, why would App update? SigninForm is not using any props and has its own state Commented Feb 4, 2021 at 21:22
  • @evolutionxbox what syntax errors? The snippet editor didnt tell me there were any, and the "Format" button gave me the code you see above..... Should I have done something else? Commented Feb 4, 2021 at 21:22
  • Ah I see. I don't think the snippet editor knows how to format JSX. Commented Feb 4, 2021 at 21:23
  • @evolutionxbox I agree it doesnt seem like App should update (Thats what I asked on the linked question). Should I put something like a useEffect hook in App to watch the value of email? I can do that. Will update the example momentarily Commented Feb 4, 2021 at 21:24

3 Answers 3

2

function App() { const [email, setEmail] = React.useState(); return ( <div> EMAIL: {email} <br></br> <SigninForm setEmail={setEmail}/> </div> ) } function SigninForm(props) { const [email, setEmail] = React.useState() var credsSubmit = (event) => { event.preventDefault(); props.setEmail('[email protected]') } return ( <div> <form onSubmit={credsSubmit}> <input type='submit' /> </form> </div> ) } ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script> <div id="root"></div>

1-in the App component you are passing setEmail as props to the SigninForm this line:

<SigninForm setEmail={setEmail}/> 

2-in the SigninForm you are creating a state variable email and a setter function to set its value setEmail that is this line:

const [email, setEmail] = React.useState() 

in SigninForm you were calling setEmail thinking that this will update state of App component where in reality you were calling the local setEmail not the one you were receiving from the props.

by calling props.setEmail you are calling the method that is coming from App component not the local one.

and here is the react guide on components and props

Sign up to request clarification or add additional context in comments.

4 Comments

Consider encouraging the SinginForm state be removed too?
@evolutionxbox i am not pretty sure if this is the desired outcome.
@AlanOmar that worked perfectly, Any chance you could explain what "props" does and why it was so important here? Or tell me what to google?
@evolutionxbox I took your suggestion and removed the extra email state from the SigninForm
1
function App() { const [email, setEmail] = React.useState(); return ( <div> EMAIL: {email} <br></br> <SigninForm setEmail={setEmail}/> </div> ) } function SigninForm(props) { var credsSubmit = (event) => { event.preventDefault(); props.setEmail('[email protected]') // changed this and removed local email state } return ( <div> <form onSubmit={credsSubmit}> <input type='submit' /> </form> </div> ) } ReactDOM.render(<App />, document.getElementById('root')); 

Comments

0

Have you tried a button?

function App() { const [email, setEmail] = React.useState(); return ( <div> EMAIL: {email} <br></br> <SigninForm setEmail={setEmail}/> </div> ) } function SigninForm() { const [email, setEmail] = React.useState() var credsSubmit = (event, data) => { event.preventDefault(); props.setEmail(data.email.toLowerCase()); } return ( <div> <form onSubmit={credsSubmit}> <input name="email" /> <button type="submit">Submit</button> </form> </div> ) } ReactDOM.render(<App />, document.getElementById('root')); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.