Как сделать так, чтобы при отправке формы сохранялись данные в переменной хука useState? - PullRequest
0 голосов
/ 25 мая 2020

Я новичок в React и JavaScript; сейчас смотрю на крючки. У меня есть эти два функциональных компонента React в приложении, которое я создал с помощью приложения Create React:

App.js

import React, { useState} from 'react';
import NameTaker from './components/NameTaker'

export default function App() {
  const [name, setName] = useState(null);

  if (name == null) {
    return <NameTaker onSubmit={submitHandler} />
  }
  return <p>Your name is: {name}</p>

  function submitHandler(e) {
    setName(e.value)
  }
}

и NameTaker.js

import React from 'react';

export default function NameTaker(props) {
  return(
    <div>
      <p>Please enter your name.</p>
      <form onSubmit={props.onSubmit}>
        <label>
          Name:
          <input type='text' name='name' />
        </label>
        <button type='submit'>Submit</button>
      </form>
    </div>
  )
}

Это оператор рендеринга в index.js:

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

Приложение работает нормально локально, и все элементы в NameTaker.js правильно отображаются на веб-странице.

Когда я заполняю имя и нажмите кнопку, я ожидаю, что он выполнит функцию обратного вызова, сохранит строку имени внутри переменной name, затем, когда компонент функции App повторно отрендерит, новое имя должно быть сохранено, а <p>Your name is: {name}</p> должен быть возвращен вместо формы при попадании в условный оператор. Но вместо этого, когда я нажимаю кнопку, URL-адрес просто изменяется, добавляя /?name=whatever в конце, а форма остается на странице.

Я попытался изменить программу, чтобы она давала обратный вызов кнопке вместо такой формы: <button onClick={props.onSubmit}>Submit</button>, но поведение не изменилось.

Я пробовал добавить e.preventDefault(); до и затем после вызова setName в моей функции обратного вызова, но это тоже не сработало .

Точное поведение, которое я ищу: , когда имя null, вернуть компонент, отображающий поле формы / ввода, использовать обратный вызов, чтобы сохранить отправленное имя в состоянии родительского компонента, повторно отобразить родительский компонент, но поскольку состояние больше не null, верните отображаемое имя абзаца вместо компонента формы.

Кто-нибудь может показать мне, как это сделать, пожалуйста?

Ответы [ 2 ]

2 голосов
/ 25 мая 2020

Вам просто нужно изменить вашу submitHandler функцию следующим образом:

  function submitHandler(e) {
    e.preventDefault();
    setName(e.currentTarget.name.value)
  }

Вам нужно e.preventDefault(), чтобы остановить повторную отрисовку страницы, хотя часто это не так необходимо, как раньше. чтобы быть, я не совсем уверен, почему.

Чтобы получить значения из формы, вы должны указать, какие значения вы хотите. e.currentTarget.name.value дает вам текущую цель (т.е. форму), затем часть .name дает вам ввод формы с именем или идентификатором name, а затем вы можете получить значение этого ввода.

const {useState} = React;
function NameTaker(props) {
  return(
    <div>
      <p>Please enter your name.</p>
      <form onSubmit={props.onSubmit}>
        <label>
          Name:
          <input type='text' name='name' />
        </label>
        <button type='submit'>Submit</button>
      </form>
    </div>
  )
}

function App() {
  const [name, setName] = useState(null);
  function submitHandler(e) {
    e.preventDefault();
    setName(e.currentTarget.name.value)
  }
  if (name == null) {
    return <NameTaker onSubmit={submitHandler} />
  }
  return <p>Your name is: {name}</p>


}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>

<div id="root"/>
0 голосов
/ 25 мая 2020
import React, { useState} from 'react';
import NameTaker from './components/NameTaker'

export default function App() {
  const [name, setName] = useState(null);

  function submitHandler(e) {
    setName(e.target.value)
  }

 return(
    {!!name ? <p>Your name is: {name}</p> : <NameTaker onSubmit={submitHandler} />
 })
}
...