Formik - name and ID are not being passed to Field - reactjs

I have a component like below, and when I pass name prop or an ID, it is not being passed to a component and I can check two radio buttons at once. Also ,how can I update a predefined field in initial values with value of a checked radio button?
In React Devtools it looks ok
I get the following error
Warning: Formik called `handleChange`, but you forgot to pass an `id` or `name` attribute to your input:
import React from "react";
import { Heading, OptionCard } from "../..";
import data from "../../../../lang/pl.json";
import { Field } from "formik";
export const Step1 = ({
errors,
touched,
values,
handleChange,
handleBlur,
handleSubmit
}) => {
console.log(values, errors, touched);
return (
<>
<div className="bottomSeparator mb-4">
<Heading variant="h3">{data["global.offer-details"]}</Heading>
</div>
<Heading variant="h5" bsClasses="my-1" info>
{data["global.category-offer"]}
</Heading>
<div className="row">
<div role="group" className="col-12">
<div className="col-xs-6 col-lg-3">
<Field
type="radio"
component={OptionCard}
value={data["create.blade.text-1"]}
name={values.kategoria}
onChange={handleChange}
id={data["create.blade.text-1"]}
name={data["create.blade.text-1"]}
/>
</div>
<div className="col-xs-6 col-lg-3">
<Field
type="radio"
component={OptionCard}
value={data["create.blade.text-2"]}
name={values.kategoria}
onChange={handleChange}
id={data["create.blade.text-2"]}
name={data["create.blade.text-2"]}
/>
</div>
</div>
<div className="row mb-3">
<div className="col-md-12 col-sm-12 col-xs-12">
<div className="form-group">
<label>
{data["global.category-offer"]}{" "}
<span className="red">
{data["global.required"]}
</span>
</label>
<select
id="type"
name="type"
className="d-block"
required="yes"
>
<option value="course">
{data["create.blade.text-1"]}
</option>
<option value="private_lesson">
{data["create.blade.text-2"]}
</option>
</select>
</div>
</div>
</div>
</div>
</>
);
};
thanks

You have values formik variable.
You defined name as name={values.kategoria} (example). When page renders, you have name={values.kategoria} equals to "".
You have also doubled name props, make always according to your data variable as you import it, as you did here name={data["create.blade.text-1"]}
Also good thing to do:
You define initialValues and assign your data to your initialValues. After, you are using {values} variable inside render component, example here:

Related

My Radio Buttons don't appear (React-Redux & Materialize CSS)

I'm trying to make a that allows users to make true/false questions. I've looked all around and can't figure out why these radio buttons don't appear in this React component (using Materialize CSS).
render() {
const { courseTitle, courseDescription } = this.props;
return (
<div className='container selection create-lecture'>
<div className='row'>
<form onSubmit={this.handleSubmit} className='white'>
<h5 className='grey-text text-darken-3'>True / False Question</h5>
<p></p>
<div className='input-field'>
<label htmlFor='questionQuestion'>Your True/False Question:</label>
<textarea className='materialize-textarea' id='questionQuestion' onChange={this.handleChange}>
</textarea>
</div>
<p>
<input id='radio-true' type="radio" value="true" checked={this.state.selectedRadioOption === "true"} onChange={this.onValueChange}/>
<label htmlFor='radio-true'>True</label>
</p>
<p>
<input id='radiofalse' type="radio" value="false" checked={this.state.selectedRadioOption === "false"} onChange={this.onValueChange}/>
<label htmlFor='radiofalse'>False</label>
</p>
<div className='input-field'>
<button className='btn custom-orange lighten-1 z-depth-0'>Create Question</button>
</div>
</form>
</div>
</div>
)
}
}
results in:
You need to use the correct markup as shown in the documentation. :
<label>
<input name="group1" type="radio" checked />
<span>Red</span>
</label>
Label (wrapper)
Input
Span
Materialize doesn't use the browser default radio. Always use the markup suggested by the docs!

React Select Always re-render, even when change another state

React Select Always re-render, even when change another state.
...
const [expense_currency, setExpenseCurrency] = React.useState(expense_claim.expense_currency);
const [remarks, setRemarks] = React.useState(expense_claim.remarks);
...
...
return (
...
<div className="form-group row p-0 col-sm-12 col-md-6">
<label className="text-nowrap col-form-label col-sm-4">Currency</label>
<div className="col-sm-8 p-0" title={expense_currency}>
<Select
className="select2"
placeholder="Select Currency"
isDisabled={false}
isClearable={true}
value={expense_currency}
options={select_currency}
onChange={selected => { setExpenseCurrency(selected.value) }}
/>
</div>
</div>
<div className="form-group row p-0 col-sm-12 col-md-6">
<label className="text-nowrap col-form-label col-sm-4">
Remarks
</label>
<div className="col-sm-8 p-0">
<textarea
className="form-control"
required={true}
disabled={false}
name="remarks"
placeholder=""
defaultValue={remarks}
onChange={e => setRemarks(e.target.value)}
></textarea>
</div>
</div>
)
SS from my chrome react profiler
i have try react-select v2.0.0 to v.2.4.4 all have same result.
can i know how to make it not rerender when i'm update my remarks fields ?
This depends on whether Select is using PureComponent or memo() or something similar. But if it is the props you pass in will break the check every time since you are creating a callback for onChange every render.
To have a consistent callback reference use useCallback:
const onSelectChange = useCallback(selected => setExpenseCurrency(selected.value), [setExpenseCurrency]);
And pass it in:
onChange={onSelectChange}
If select_currency is a non-primitive e.g. array or object you will need to ensure that is a consistent reference too. You didn't post that so can't advise.

Scoping during Login with React and react-redux-firebase

I am using react-redux-firebase for authentication and user management.Once users login, I want to navigate the user to their dashboard with an url of 'dahboard/userId.' When the user authenticate firebase gives us a response that has the user's ID there. The problem is when I attempt to complete a nav request via 'this.history.push('dahsboard/uid') I keep getting an error that says 'this' is undefined. I'm pretty sure it is a scoping issue but I cannot figure out exactly how I need to structure the code to solve the problem.
I have already tried to store the uid as a const. I have also tried chaining another async funciton to the request. Either this.props is undefined or the uid is undefined.
onSubmit = (e) => {
e.preventDefault();
// this.props.signIn(this.state);
this.props.firebase.login(this.state)
.then(function(res){
const userId = res.user.user.uid;
console.log(userId);
this.props.push('/dashboard/userId');
// ! Scoping issue - How to get 'props' in or userId out of this scope
})
.catch(
err => console.log(err.message),
)
}
render() {
const authError = this.props.authError;
return(
<div className="container">
<div className="row">
<div className="col-sm-9 col-md-7 col-lg-5 mx-auto">
<div className="card card-signin my-5">
<div className="card-body">
<div className = "red-text center">
{authError ? <p> {authError.message} </p> : null}
</div>
<h5 className="card-title text-center">Sign In</h5>
<form className="form-signin" onSubmit={this.onSubmit}>
<div className="form-label-group">
<label>Email address
<input type="email" id="inputEmail" className="form-control" placeholder="Email address" value={this.state.email} onChange={this.onChangeEmail} required autoFocus />
</label>
</div>
<div className="form-label-group">
<label>Password
<input type="password" id="inputPassword" className="form-control" placeholder="Password"
value={this.state.password}
onChange={this.onChangePassword}
required />
</label>
</div>
<div className="custom-control custom-checkbox mb-3">
<input type="checkbox" className="custom-control-input" id="customCheck1" />
<label className="custom-control-label" >Remember password
</label>
</div>
<button className="btn btn-lg btn-primary btn-block text-uppercase" type="submit">Sign in</button>
<hr className="my-4" />
</form>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default compose(
//map firebase redux to props
firebaseConnect((props) => {
}),
connect(
//map redux-state to props
(state) => ({
userId: state.firebase.auth.uid,
authError: state.firebase.authError,
auth: state.firebase.auth
})
)
)(Login)
You need to use withRouter from "react-router" like so:
export default withRouter(connect(mapStateToProps, {
...
})(App));
Then it will be accessible through this.props;
You can also pass history through props from App if you have a nested component like so:
<NestedComponent history={this.props.history}/>

"Expected an assignment but found an expression"

I'm working on a project with my classmates, but while trying to load this page in react I get the error: "Expected an assignment or function call and instead saw an expression" that's appeared on several of her pages. I looked into it and it seems to be a warning that ES Lint throws out, but I'm unsure of how to fix it for my particular issue. Any help would be appreciated.
Code Snippet::
import React from "react";
import './LoginPage.css';
import GlobalNav from '../../components/GlobalNav';
import GlobalFooter from '../../components/GlobalFooter/GlobalFooter';
const LoginPage = props => {
<div>
<GlobalNav />
<h1 className="uk-text-center blueText">login</h1>
<div className="uk-container"/>
<form className="authorForm uk-width-1-2#m uk-align-center uk-form-stacked">
<p className="uk-text-lead">Login and add some Highlights of your own.</p>
<p className="uk-text-center redText"><span uk-icon="bolt"></span></p>
<fieldset className="uk-fieldset">
<div className="form-group">
<div className="uk-margin">
<label className="uk-form-label" for="form-stacked-select">* Email:</label>
<div className="uk-inline uk-width-1-1">
<span className="uk-form-icon uk-form-icon-flip blueText" uk-icon="icon: world"></span>
<input className="uk-input" id="email" name="email" type="text"></input>
</div>
</div>
<div className="uk-margin">
<label className="uk-form-label" for="form-stacked-select">* Password:</label>
<div className="uk-inline uk-width-1-1">
<span className="uk-form-icon uk-form-icon-flip blueText" uk-icon="icon: lock"></span>
<input className="uk-input" id="password" name="password" type="text"></input>
</div>
</div>
<button className="uk-button uk-button-secondary redText uk-align-center" id="submit-btn"><span uk-icon="user"></span> login</button>
</div>
</fieldset>
</form>
<GlobalFooter />
</div>
}
export default LoginPage;
You forgot to enclose them in a return statement.
const LoginPage = props => {
// this is where you put your logic if needed before returning JSX codes
return (
<div>
// ...rest of the codes
</div>
);
};
or, you can simply do this, since you're using ES6 arrow function:
const LoginPage = props => (
<div>
// ...rest of the code
</div>
);

Facing issue while adding radio button in react - input is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`

Input is a void element tag and must neither have children nor use dangerouslySetInnerHTML.
render() {
let radioid = this.props.radioid;
return (
<div className="row">
{this.props.options.map(function(option) {
return (
<div key={radioid} className="column">
<input type="radio" name={radioid} value={option}>
<label>{option}</label>
</input>
</div>
);
})}
</div>
);
}
For example options is a list of elements like A, B, C, D
As per the error, the input tag should not have any children, take the label out of input closure tag
render() {
let radioid = this.props.radioid;
return (
<div className="row">
{this.props.options.map(function(option) {
return (
<div key={radioid} className="column">
<label>{option}</label>
<input type="radio" name={radioid} value={option}/>
</div>
);
})}
</div>
);
}
You get the error coz in input tag in jsx should be self closing, so after return always jsx script should write.
render() {
let radioid = this.props.radioid;
return (
<div className="row">
{this.props.options.map(function(option) {
return (
<div key={radioid} className="column">
<label>{option}</label>
<input type="radio" name={radioid} value={option}/>
</div>
);
})}
</div>
);
}
HTML elements such as <area />, <br />, and <input /> are void elements which are only self-closing without any content.
Therefore, React will throw an exception if you set either children or dangerouslySetInnerHTML prop for a void element.
So, instead of writing this as
<div key={radioid} className="column">
<input type="radio" name={radioid} value={option}>
<label>{option}</label>
</input>
</div>
write it like this:
<div key={radioid} className="column">
<input type="radio" name={radioid} value={option}/>
<label>{option}</label>
</div>
Give a thumbs up if you like this answer.
In react inputs have to end with a single tag, not like
<input type="submit">Submit</input>
so write
<input />
but this may show submit query so write
<input value="Submit or login or whatever you like">
There you go :)
Thanks very much!
I solved.
I have 2 tags "input", a type text and button but just the first didn't worked.
<input type="text" onChange={(event)=>{this.setState({coinAvalue:event.target.value})}}>
<input type="button" value="Converter"onClick={this.converter}>
You should use a self-closing input tag like:
<input className="card-field-input" placeholder="text"/>
In my case, I had a select without the as='select' in my <Form.Control> call of react-bootstrap. So React rendered an <input> instead of a <select>
<Form.Control as='select' >
<option value="Buy">Buy</option>
<option value="Sell">Sell</option>
</Form.Control>

Resources