запретить пользователю добавлять имена

#reactjs

#reactjs

Вопрос:

Мне нужно запретить пользователю добавлять имена, которые уже существуют в списке пользователей, но я не уверен, куда мне его добавить, а также какой метод лучше использовать .includes или indexOf ? Я хочу выдавать предупреждение с помощью команды alert при попытке такого действия. Любая помощь была бы очень кстати!

 import React, { useState } from 'react'


const App = () => {
  const [ persons, setPersons ] = useState([  { name: 'Arto Hellas' }]) 
  const [ newName, setNewName ] = useState('')

  const addName = (event) => {
      event.preventDefault()
      const nameObject = {
          name: newName,
      }
      setPersons([...persons,nameObject])
  }

  const handleNameChange = (event) => {
      setNewName(event.target.value)
  }
 

  return (
    <div>
      <h2>Phonebook</h2>
      <form onSubmit={addName} >
        <div>
          name: <input value={newName} onChange={handleNameChange} />
        </div>
        <div>
          <button type="submit">add</button>
        </div>
      </form>
      <h2>Numbers</h2>
        {persons.map(person => (
            <p key={person.name}>{person.name}</p>
        ))}
        
    </div>
  )
}

export default App
  

Комментарии:

1. Ни один из этих методов массива не принимает обратный вызов, что делает невозможным (насколько я знаю) использовать его для проверки существования на основе свойства объекта. Я бы посоветовал изучить find .

Ответ №1:

Вам нужно что-то сделать в следующем месте:

   const addName = (event) => {
    event.preventDefault();
    const nameObject = {
      name: newName
    };
    setPersons([...persons, nameObject]);
  };
  

Используйте .find() в persons массиве, чтобы найти конкретное имя, которое уже существует, и добавить условие перед setPersons выполнением.

 if (persons.find(p => p.name === newName)) {
  window.alert("Name already exists!");
  return false;
}
  

Код, подобный приведенному выше, будет работать.

 import React, { useState } from "react";

const App = () => {
  const [persons, setPersons] = useState([{ name: "Arto Hellas" }]);
  const [newName, setNewName] = useState("");

  const addName = (event) => {
    event.preventDefault();
    if (persons.find((p) => p.name === newName)) {
      window.alert("Name already exists!");
      return false;
    }
    const nameObject = {
      name: newName
    };
    setPersons([...persons, nameObject]);
  };

  const handleNameChange = (event) => {
    setNewName(event.target.value);
  };

  return (
    <div>
      <h2>Phonebook</h2>
      <form onSubmit={addName}>
        <div>
          name: <input value={newName} onChange={handleNameChange} />
        </div>
        <div>
          <button type="submit">add</button>
        </div>
      </form>
      <h2>Numbers</h2>
      {persons.map((person) => (
        <p key={person.name}>{person.name}</p>
      ))}
    </div>
  );
};

export default App;
  

Демонстрация: https://codesandbox.io/s/nervous-poitras-i3stw?file=/src/App.js:0-958

Приведенный выше код показывает уродливое предупреждение об ошибке, используя обычное оконное предупреждение. Если вам нужна лучшая ошибка, подобная этой:

Предварительный просмотр

Вы можете использовать следующий код, установив состояние:

 import React, { useState } from "react";
import "./styles.css";

const App = () => {
  const [persons, setPersons] = useState([{ name: "Arto Hellas" }]);
  const [newName, setNewName] = useState("");
  const [error, setError] = useState(false);

  const addName = (event) => {
    event.preventDefault();
    if (persons.find((p) => p.name === newName)) {
      setError(true);
      return false;
    }
    const nameObject = {
      name: newName
    };
    setPersons([...persons, nameObject]);
  };

  const handleNameChange = (event) => {
    setNewName(event.target.value);
  };

  return (
    <div>
      <h2>Phonebook</h2>
      <form onSubmit={addName}>
        {error amp;amp; <p className="error">User already exists.</p>}
        <div>
          name: <input value={newName} onChange={handleNameChange} />
        </div>
        <div>
          <button type="submit">add</button>
        </div>
      </form>
      <h2>Numbers</h2>
      {persons.map((person) => (
        <p key={person.name}>{person.name}</p>
      ))}
    </div>
  );
};

export default App;
  

И вот наш style.css :

 .error {
  background-color: red;
  color: #fff;
  padding: 5px;
}
  

Демонстрация: https://codesandbox.io/s/vibrant-tree-wsou2?file=/src/App.js

Ответ №2:

Сначала добавьте поле, чтобы проверить, существует имя или нет:

 const nameExists = React.useMemo(() => {
    return persons.some(item => item.name === newName);
  }, [newName, persons])
  

Затем отключите кнопку и покажите сообщение, если имя существует:

 <div>
          {nameExists amp;amp; <p>Name {newName} already exists!</p>}
          <button type="submit" disabled={nameExists} >add</button>
        </div>
  

Кроме того, убедитесь, что вы очистили имя при добавлении нового имени:

 const addName = (event) => { 
      ... 
      setNewName('')
  }
  

 const App = () => {
  const [ persons, setPersons ] = React.useState([  { name: 'Arto Hellas' }]) 
  const [ newName, setNewName ] = React.useState('')

  const addName = (event) => {
      event.preventDefault()
      const nameObject = {
          name: newName,
      }
      setPersons([...persons,nameObject]);
      
      setNewName('')
  }

  const handleNameChange = (event) => {
      setNewName(event.target.value)
  }
  
  const nameExists = React.useMemo(() => {
    return persons.some(item => item.name === newName);
  }, [newName, persons])
 

  return (
    <div>
      <h2>Phonebook</h2>
      <form onSubmit={addName} >
        <div>
          name: <input value={newName} onChange={handleNameChange} />
        </div>
        <div>
          {nameExists amp;amp; <p>Name {newName} already exists!</p>}
          <button type="submit" disabled={nameExists} >add</button>
        </div>
      </form>
      <h2>Numbers</h2>
        {persons.map(person => (
            <p key={person.name}>{person.name}</p>
        ))}
        
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'))  
 <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>  

Ответ №3:

Вы можете использовать метод find для поиска пользователя с newName помощью . Пожалуйста, проверьте приведенный ниже фрагмент кода:

 const addName = (event) => {
    event.preventDefault()
    const nameObject = {
        name: newName,
    }
    let personAlreadyExists = persons.find(person => person.name === newName);

    if (personAlreadyExists) {
        alert('Person with that name already exists');
        // any other operations (like clearing user input in the form, etc..)
    }
    else {
        setPersons([...persons, nameObject])
    }
}
  

Код-изолированная среда

Комментарии:

1. Не добавляйте пустые ссылки изолированной среды