Programmatically control the properties of a component - reactjs

Suppose I have a component that a parameter from another component called jobData. The component could be a value or be undefined. If it has a value, I want to assign it to a textField property called defaultValue. If jobData is undefined, I want to assign it to something else. I tried the below in my code, but it didn't work. Is there any/another way to do this?
import React from 'react'
import {Dialog, TextField} from '#mui/material'
export default function myFunction({jobData}) {
return(
<div>
<form>
<TextField
autoFocus
margin="dense"
width="100%"
id="my_id"
label="My ID"
type="text"
name="myID"
defaultValue={if({jobData.length} > 0){
{jobData[0]['id']}
} else { {jobData.length.toString()}
}
/>
</form>
</div>
)

Try using encapsulation
import React from 'react'
import {Dialog, TextField} from '#mui/material'
export default function myFunction({jobData}) {
function isJobDataUndefined(){
if(jobData.length > 0){
return jobdata[0]['id']
}
return jobData.length.toString()
}
return(
<div>
<form>
<TextField
autoFocus
margin="dense"
width="100%"
id="my_id"
label="My ID"
type="text"
name="myID"
defaultValue={isJobDataUndefined()}
/>
</form>
</div>
)

Related

'signUpComponent' is declared but its value is never read.ts(6133)

I want to import the following components from the app component.
I don't know if the following reason appears.
: 'signUp Component' is declared but its value is not read
Also, clicking the button doesn't work. How can I solve it?
import logo from './logo.svg';
import './App.css';
import {useState} from 'react';
import signUpComponent from './SignUpComponent';
function App() {
const [signUpState, setSignUpState] = useState(false);
function controllSignUp(){
setSignUpState(!signUpState)
}
return (
<div className="App">
<div className ="SignIn">
<h1>LOGIN</h1>
<form className = "loginForm">
<label htmlFor="email">email</label>
<input
id="email"
type="email"
name="email"
placeholder="test#email.com"
/>
<label htmlFor="password">password</label>
<input
id="password"
type="password"
name="password"
placeholder="****************"
/>
<button type="submit">login</button>
</form>
<button onClick={controllSignUp}>signin</button>
{signUpState && <signUpComponent/>}
</div>
</div>
);
}
export default App;
User-Defined Components Must Be Capitalized.
Instead of
import signUpComponent from './SignUpComponent';
you need to do
import SignUpComponent from './SignUpComponent';

#mui/material <Checkbox> with Formik

I wish to build a React (multi step) form using Formik and Mui. I cannot understand how to bind/control the mui checkbox element
import { Button, Checkbox, Typography } from "#mui/material";
import { Field, Form, Formik } from "formik";
import "./styles.css";
export default function App() {
var fruitValues = ["apple", "banana"];
function handleSubmit(values, actions) {
fruitValues = values.fruit;
console.debug(values.fruit);
}
return (
<div className="App">
<Formik initialValues={{ fruit: ["apple"] }} onSubmit={handleSubmit}>
<Form id="test2">
<Checkbox name="fruit" value="apple" label="Apple" />
<Checkbox name="fruit" value="banana" label="Banana" />
<Checkbox name="fruit" value="orange" label="Orange" />
<Button type="submit">Submit</Button>
</Form>
</Formik>
</div>
);
}
See https://codesandbox.io/s/thirsty-wing-91glso?file=/src/App.js:0-1380
I am working on this as well. Seems like something that should be covered in the docs but just isn't.
There is this example. It covers doing something like this ...
<Form>
<Field
type="email"
name="email"
component={TextField}
color={"error"}
/>
But there isn't any explanation of where this comes from or what is happening here.
My reaction is a little late but I faced the same issue and made it work as follow.
import React from 'react'
import { Field, Form, Formik } from 'formik'
import Checkbox from '#mui/material/Checkbox'
import FormControlLabel from '#mui/material/FormControlLabel'
export default function Example() {
return (
<Formik>
<Form>
<Field name="terms_of_condition">
{({ field }) => (
<FormControlLabel
onChange={field.onChange}
control={<Checkbox name="terms_of_condition" />}
label="Terms of conditions"
sx={sx}
value="on"
/>
)}
</Field>
</Form>
</Formik>
)
}

Using input state in different components

I want to use the state of the input in another component in React. So I have a component and in this component, I have a form.
import React, { useState } from "react";
import { Form } from "react-bootstrap";
function Jumbotron() {
const [inputFrom, setInputFrom] = useState("");
return (
<Form className="shadow p-3 mb-5">
<Form.Group controlId="formGroupFrom">
<Form.Label className="form-subtitle">Title</Form.Label>
<Form.Control
type="text"
placeholder="Enter input"
onChange={(event) => setInputFrom(event.target.value)}
/>
</Form.Group>
</Form>
);
}
export default Jumbotron;
So I want to use the 'inputFrom' in other component and I just want to show it. I will do it in several components so could you give me an advice about it?
import React from "react";
import { Container } from "react-bootstrap";
function Checkout() {
return (
<Container>
<div className="shipment-info">
<div className="basic">
<div className="col-2 title">From</div>
<div className="col-4 info">{inputFrom}</div>
</div>
</div>
</Container>
);
}
export default Checkout;
You can pass down the prop to another component like so
<NextComponent propYouWantToPass={inputFrom} />
and use it in the next component like props.propYouWantToPass, assuming you got the props in the next component settings props as a parameter
const NextComponent = (props) => {
return(
<View>
<Text>{props.propYouWantToPass}</Text>
</View>
)
}
As other already said, if you are planning to use Checkout component inside Jumbotron component as a child.
The solution is easy, you just pass inputForm as prop to Checkout and receive or inherit from Jumbotron
Could be something like this:
import React, { useState } from "react";
import { Form } from "react-bootstrap";
import { Checkout } from "./Checkout";
function Jumbotron() {
const [inputFrom, setInputFrom] = useState("");
return (
<>
<Form className="shadow p-3 mb-5">
<Form.Group controlId="formGroupFrom">
<Form.Label className="form-subtitle">Title</Form.Label>
<Form.Control
type="text"
placeholder="Enter input"
onChange={(event) => setInputFrom(event.target.value)}
/>
</Form.Group>
</Form>
{/* <-- give any name instead "inputData" */}
<Checkout inputData={inputForm} />
</>
);
}
export default Jumbotron;
Found your inputForm on Checkout as props.inputData
*Ref: https://reactjs.org/docs/components-and-props.html#rendering-a-component

react-hook-form Controller issues

Hi im trying to do one form with react-hook-form and material-ui. I don't want to write Controller every time for all TextFields. Because of that i declare it in another file and call it in my form but its not working i didn't understand why, because in some videos that i watched is working. What is the problem and how i can fix it ?
Form Field
import React from 'react'
import { TextField, Grid } from '#material-ui/core'
import { useForm, Controller, useFormContext } from 'react-hook-form'
const FormField = ({name, label}) => {
const { control } = useForm()
return (
<Grid item xs={12} sm={6} >
<Controller
render = {({field}) =>
<TextField
{...field}
label={label} required
/>}
name={name}
control = {control}
defaultValue=""
/>
</Grid>
)
}
export default FormField
Adress Form
import React from 'react'
import { InputLabel, Select, MenuItem, Button, Grid, Typography, TextField } from '#material-ui/core'
import { useForm, FormProvider, Controller } from 'react-hook-form'
import FormField from './FormField'
import { Link } from 'react-router-dom'
const AdressForm = ({next}) => {
const {handleSubmit, control} = useForm()
return (
<>
<Typography variant="h6" gutterBottom>Shipping Address </Typography>
<form onSubmit={handleSubmit((data) => console.log(data) )}>
<Grid container spacing={3}>
<FormField name='firstName' label='First Name' required='required'/>
<FormField name='lastName' label='Last Name' />
<FormField name='email' label='Email' />
<FormField name='phoneNumber' label='Phone Number' />
</Grid>
<br/>
<div style={{ display: 'flex', justifyContent: 'space-between'}}>
<Button component={Link} to="/cart" variant="outlined">Back to Cart</Button>
<Button type="submit" variant="contained" color="primary">Next</Button>
</div>
</form>
</>
)
}
export default AdressForm
You must use one useForm hook for each form, in your code, you call useForm in every Field components, creating multiple independent form states, which leads to unexpected result.
What you need to do is to call useForm in the parent element and pass the dependencies (register, formState, error...) down the child components, so your form can have one unified state. If you have a deeply nested components, you can use useFormContext to pass the form context to the nested children easily:
import React from "react";
import { useForm, FormProvider, useFormContext } from "react-hook-form";
export default function App() {
const methods = useForm();
const onSubmit = data => console.log(data);
return (
<FormProvider {...methods} > // pass all methods into the context
<form onSubmit={methods.handleSubmit(onSubmit)}>
<NestedInput />
<input type="submit" />
</form>
</FormProvider>
);
}
function NestedInput() {
const { register } = useFormContext(); // retrieve all hook methods
return <input {...register("test")} />;
}

Problem connect Redux with parent props from React

I have been trying for several days to solve a problem between connect of redux and a props of a parent component. I use redux in my child component and at the same time use props to call a handlechange function and a state of the parent component.
When in the child component use connect does not update this.props.args properly, however in the parent there is no problem. Then I have a validation so that when all the fields are complete, my submit button will be activated.
Additionally implement a state and a function in the parent component to detect the movement of the mouse and pass it to the child component, to clear some doubts, the amazing thing is that in this case if it detects changes in this.props.mouse and much more rare is that when I fill a field and then move the mouse, my this.props.args in the child component if it is updated. I'm a little disconcerted and I do not know what is due.
Parent Component:
import React, { Component } from "react";
import SignUp from './login/SignUp';
class Login extends Component {
state = {
showRegister: true,
argsSignup: {},
move: {},
}
handleChange = (ev, input) => {
let argsSignup = this.state.argsSignup;
argsSignup[input.name] = input.value;
this.setState({argsSignup});
//console.log(this.state.argsSignup);
}
handleMouseMove = (event) => {
this.setState({
move: {
x: event.clientX,
y: event.clientY
}
});
}
render() {
const {showRegister, argsSignup, move} = this.state;
return(
<div onMouseMove={this.handleMouseMove}>
{showRegister && <SignUp args={argsSignup} handleChange={this.handleChange} mouse={move} />}
</div>
);
}
}
export default (Login);
Child Component (with connect):
import React, { Component } from "react";
import { connect } from "react-redux";
import { Form, Button } from 'semantic-ui-react';
import { signInFacebook } from "../../redux/createActions";
class SignUp extends Component {
render() {
const {args, handleChange, signInFacebook} = this.props;
return(
<React.Fragment >
<Form >
<Form.Field>
<Form.Input name='email' onChange={handleChange} placeholder='numero de movil o correo electronico' />
</Form.Field>
<Form.Field>
<Form.Input name='name' onChange={handleChange} placeholder='Nombre completo'/>
</Form.Field>
<Form.Field>
<Form.Input name='username' onChange={handleChange} placeholder='Nombre de usuario' />
</Form.Field>
<Form.Field>
<Form.Input name='password' onChange={handleChange} type="password" placeholder='contraseña' />
</Form.Field>
<Button
type='submit'
disabled={!args.email || !args.username || !args.name || !args.password }
primary
fluid>
Regístrate
</Button>
</Form>
<button onClick={signInFacebook}>Inicia sesion con Facebook</button>
</React.Fragment>
)
}
}
export default connect(null, {signInFacebook})(SignUp);
On the other hand, if I delete the connect from my child component, everything works great and if it detects the changes of this.props.args
Child Component (without connect):
import React, { Component } from "react";
import { connect } from "react-redux";
import { Form, Button } from 'semantic-ui-react';
import { signInFacebook } from "../../redux/createActions";
class SignUp extends Component {
render() {
const {args, handleChange, signInFacebook} = this.props;
return(
<React.Fragment >
<Form >
<Form.Field>
<Form.Input name='email' onChange={handleChange} placeholder='numero de movil o correo electronico' />
</Form.Field>
<Form.Field>
<Form.Input name='name' onChange={handleChange} placeholder='Nombre completo'/>
</Form.Field>
<Form.Field>
<Form.Input name='username' onChange={handleChange} placeholder='Nombre de usuario' />
</Form.Field>
<Form.Field>
<Form.Input name='password' onChange={handleChange} type="password" placeholder='contraseña' />
</Form.Field>
<Button
type='submit'
disabled={!args.email || !args.username || !args.name || !args.password }
primary
fluid>
Regístrate
</Button>
</Form>
<button onClick={signInFacebook}>Inicia sesion con Facebook</button>
</React.Fragment>
)
}
}
export default (SignUp);
I appreciate your help from now on. Thank you!!
When you connect your component, you are establishing a connection with Redux and the props of that component will be fed by the entire application state.
export default connect(mapStateToProps, {signInFacebook})(SignUp);
Your first parameter for connect function holds the mapStateToProps function which essentially maps the application state to props of the SignUp component. Keeping that null means that you're expecting a null state object from Redux and hence you are unable to get the desired result in this.props.args. Removing connect statement makes the props which are passed down to the child component accessible through this.props. That's the crux of Redux.

Resources