I have a problem with my <Field as="select"> in Formik. The onChange doesn't work well - no matter what option I choose, when I submit my form, it sends player1 and player2 as empty string.
E.g. output from console.log(values):
{ id: '10', player1: '', player2: '', winner: '1', date: '2021-12-16' }
When I remove the onChange it works well, but I need onChange and selectedPlayer states, because if I pick a player1, I don't want him to be visible in second option and vice versa.
Why the value property doesn't change in my Field when the selectedPlayer is being changed? It seems like it gets the initialValue from selectedPlayer which is empty string.
import { Field, Form, Formik } from 'formik';
import { connect } from 'react-redux';
import {addMatchAction} from "../../ducks/matches/operations";
import {getAllPlayers} from "../../ducks/players/selectors";
import {useState} from "react";
const MatchesForm = ({ addMatchAction,error,players }, props) => {
const handleSubmit = (values) => {
console.log(values)
addMatchAction(values);
}
const [selectedPlayer1,setSelectedPlayer1] = useState('')
const [selectedPlayer2,setSelectedPlayer2] = useState('')
return (
<div>
<h3>Add match</h3>
<Formik
initialValues={{
id: '',
player1: '',
player2: '',
winner: '',
date: ''
}}
onSubmit={(values) => handleSubmit(values)}
enableReinitialize={true}>
<Form>
<label htmlFor="id">Id: </label>
<Field name="id" />
<label htmlFor="player1">Player 1: </label>
<Field as="select" name="player1" onChange={(e) => setSelectedPlayer1(e.target.value)} value={selectedPlayer1}>
<option disabled value="">(Select a player 1)</option>
{players && players.map(player => {
if (player.id !== selectedPlayer2) {
return (
<option value={player.id}>{player.firstName} {player.lastName}</option>
)
}
}) }
</Field>
<p>
<label htmlFor="player2">Player 2: </label>
<Field as="select" name="player2" onChange={(e) => setSelectedPlayer2(e.target.value)} value={selectedPlayer2}>
<option disabled value="">(Select a player 2)</option>
{players && players.map(player => {
if (player.id !== selectedPlayer1) {
return (
<option value={player.id}>{player.firstName} {player.lastName}</option>
)
}
}) }
</Field>
</p>
<label htmlFor="winner">Winner: </label>
<Field as="select" name="winner">
<option disabled value="">Pick a winner</option>
{players && players.map(player => {
if (player.id === selectedPlayer1 || player.id === selectedPlayer2 ) {
return (
<option value={player.id}>{player.firstName} {player.lastName}</option>
)
}
})}
</Field>
<label htmlFor="date">Date: </label>
<Field name="date" type="date" />
<button type="submit">
Zatwierdz
</button>
</Form>
</Formik>
<p>{error && (<span>{error.name} {error.response.message}</span>)}</p>
</div>
)
}
const mapStateToProps = (state) => {
return {
error: state.error.error,
players: getAllPlayers(state)
}
}
const mapDispatchToProps = ({
addMatchAction
});
export default connect(mapStateToProps, mapDispatchToProps)(MatchesForm);