Input value is showing undefined (reading 'value') while using rsuite library - reactjs

It is basically rsuite#4.10.2 version
const [user, setuser] = useState('')
<InputGroup>
<Input type='text' value={user} onChange={e=>{setuser(e.target.value)}} id="user"/>
<InputGroup.Button>
<Icon icon="user" />
</InputGroup.Button>
</InputGroup>
also i have provided with the error image just look this out
enter image description here

rsuite library return the value directly in the onChange function.
So, instead:
onChange={e=>{setuser(e.target.value)}}
You should write
onChange={value=>{setuser(value)}}
This is a class that I have written with rsuite / bootstrap and basic input. You can see the difference and copy/paste the part that you want.
import React, { useState } from 'react';
import { InputGroup, Input } from 'rsuite';
import InputGroupBoostrap from 'react-bootstrap/InputGroup';
import FormControlBoostrap from 'react-bootstrap/FormControl';
const Question2 = () => {
const [user, setUser] = useState('example');
return (
<>
{/* rsuite */}
<InputGroupBoostrap>
<Input type='text' value={user} onChange={value=>{ setUser(value)}} id="user"/>
<InputGroup.Button>
Button
</InputGroup.Button>
{/* Bootstrap */}
</InputGroupBoostrap>
<InputGroupBoostrap>
<InputGroupBoostrap.Text>User 1</InputGroupBoostrap.Text>
<FormControlBoostrap value={user} onChange={(e) => { setUser(e.target.value); }} placeholder="user" />
</InputGroupBoostrap>
{/* input */}
<div>
<span>User 2</span>
<input value={user} onChange={(e) => { setUser(e.target.value); }}/>
</div>
</>
);
}
export default Question2;
I hope I've helped

Related

Blank white screen on localhost:3000 in my react project

I am getting blank white screen on localhost:3000 in my React project. The components dont get rendered. I guess the issue is with one component, because when i comment out that component(SearchForm.js) from JSX, the other components do show up. Kindly highlight what could be the possiblities causing the issue. Thanks
SearchForm.js
import { Form, Col } from 'react-bootstrap'
export default function SearchForm({ params, onParamChange }) {
return (
<Form className="mb-4">
<Form.Row className="align-items-end">
<Form.Group as={Col}>
<Form.Label>Description</Form.Label>
<Form.Control onChange={onParamChange} value={params.description} name="description" type="text" />
</Form.Group>
<Form.Group as={Col}>
<Form.Label>Location</Form.Label>
<Form.Control onChange={onParamChange} value={params.location} name="location" type="text" />
</Form.Group>
<Form.Group as={Col} xs="auto" className="ml-2">
<Form.Check onChange={onParamChange} value={params.full_time} name="full_time" id="full-time" label="Only Full Time" type="checkbox" className="mb-2" />
</Form.Group>
</Form.Row>
</Form>
)
}
App.js
import React, { useState } from 'react';
import useFetchJobs from './useFetchJobs'
import { Container } from 'react-bootstrap'
import Job from './Job'
import JobsPagination from './JobsPagination';
import SearchForm from './SearchForm';
function App() {
const [params, setParams] = useState({})
const [page, setPage] = useState(1)
const { jobs, loading, error, hasNextPage } = useFetchJobs(params, page)
function handleParamChange(e) {
const param = e.target.name
const value = e.target.value
setPage(1)
setParams(prevParams => {
return { ...prevParams, [param]: value }
})
}
return (
<Container className="my-4">
<h1 className="mb-4">GitHub Jobs</h1>
<SearchForm params={params} onParamChange={handleParamChange} />
<JobsPagination page={page} setPage={setPage} hasNextPage={hasNextPage} />
{loading && <h1>Loading...</h1>}
{error && <h1>Error. Try Refreshing.</h1>}
{jobs.map(job => {
return <Job key={job.id} job={job} />
})}
<JobsPagination page={page} setPage={setPage} hasNextPage={hasNextPage} />
</Container>
)
}
export default App;
This seems okay, will need more information, Like how did you import and use it in another file.
After trying it out, I decided to just import { Row } directly from react-bootstrap.
But if you would like to continue with Form.Row, try checking how you imported bootstrap in index.js
import "bootstrap/dist/css/bootstrap.css";

react-datetime dropdown has missing styles(css)

I am making a calendar app that whenever someone clicks the input field, it should appear as a dropdown menu and in that dropwdown menu it should let me select the fields. The styles are missing for the dropdown.
This is how it should appear:
This is how it appears now:
Here is the code where I have my calendar:
import React, {useState} from 'react'
import Modal from "react-modal"
import Datetime from 'react-datetime';
function AddEvent({isOpen, onClose, onEventAdded}) {
const [title, setTitle] = useState("")
const [start, setStart] = useState(new Date())
const [end, setEnd] = useState(new Date())
const onSubmit = (e) => {
e.preventDefault()
onEventAdded({
title,
start,
end
})
onClose()
}
return (
<Modal isOpen={isOpen} onRequestClose={onClose}>
<form onSubmit={onSubmit}>
<input placeholder="Title" value={title} onChange={e => setTitle(e.target.value)} />
<div>
<label>Start Date</label>
<Datetime value={start} onChange={date => setStart(date)} />
</div>
<div>
<label>End Date</label>
<Datetime value={end} onChange={date => setEnd(date)} />
</div>
<button>Add Event</button>
</form>
</Modal>
)
}
export default AddEvent
You need to import the corresponding css for the react-datetime library for the DatePicker to have the correct style.
This should fix it:
import "react-datetime/css/react-datetime.css";
In case you run into trouble I've replicated your issue in this codesandbox where you can see it working https://codesandbox.io/s/quiet-sound-l6t6h?file=/src/Test.tsx:113-161
Additional info, it's also explained here https://www.npmjs.com/package/react-datetime (worth reading)

Console Log from Props

I'm confused as I have managed to get my data to be logged via different means, but confused as to why when I use props for the data (rather than repeating code) it will not log the input.
For reference, I have a field component that will take props to drive what my react-hook-form TextField will request. I'd like to expand on the component but until it logs my data, I cannot proceed!
Below is the code that actually logs my data:
import React from "react";
import { useForm, Controller } from "react-hook-form";
import { TextField, Button } from "#material-ui/core/";
const NewRequest = () => {
const { register, handleSubmit, control } = useForm();
const onSubmit = (data) => console.log(data);
return (
<div>
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
control={control}
name='firstName'
render={({ field: { onChange, onBlur, value, name, ref } }) => (
<TextField
label='First Name'
variant='filled'
size='small'
onBlur={onBlur}
onChange={onChange}
checked={value}
inputRef={ref}
/>
)}
/>
<br />
<br />
<Button type='submit' variant='contained'>
Submit
</Button>
</form>
</div>
);
};
export default NewRequest;
I have then moved the Controller, TextField to create a component:
import React from "react";
import { Controller, useForm } from "react-hook-form";
import { TextField } from "#material-ui/core/";
const TextFieldComponent = (props) => {
const { name, label, size, variant } = props;
const { control } = useForm();
return (
<div>
<Controller
control={control}
name={name}
render={({ field: { onChange, onBlur, value, ref } }) => (
<TextField
label={label}
variant={variant}
size={size}
onBlur={onBlur}
onChange={onChange}
checked={value}
inputRef={ref}
/>
)}
/>
</div>
);
};
export default TextFieldComponent;
Which I am using inside of another component (to generate a full form) and passing through my props (I will make a different component for Button, but for now it is where it is):
import React from "react";
import { useForm, Controller } from "react-hook-form";
import TextFieldComponent from "./form-components/text-field";
import { Button } from "#material-ui/core/";
const NewRequest= () => {
return (
<div>
<TextFieldComponent
name='firstName'
label='First Name'
size='small'
variant='filled'
/>
<br />
<br />
<Button type='submit' variant='contained'>
Submit
</Button>
</div>
);
};
export default NewRequest;
Now pushing that component into an index.js file to render a form:
import React from "react";
import NewVendorForm from "../components/new-vendor-request";
import { useForm } from "react-hook-form";
const Home = () => {
const { handleSubmit } = useForm();
const onSubmit = (data) => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<NewVendorForm />
</form>
);
};
export default Home;
I'm stumped as to why this way would
a) customise my TextField in my form as intended
b) but not log my data as requested
I'm sure there is a very valid, basic reason as to why and it is my lack of understanding of console logging, but am in need of help to resolve!
Many thanks in advance.
The issue is that, in the refactored code, you're calling useForm twice, each of which generates a different control and data. You probably want to call useForm at the top level only, and pass in whatever you need (in particular control) to the form fields.
const Home = () => {
const { handleSubmit, control } = useForm();
const onSubmit = (data) => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<NewVendorForm control={control} />
</form>
);
};
const NewRequest= ({control}) => {
return (
<div>
<TextFieldComponent
name='firstName'
label='First Name'
size='small'
variant='filled'
control={control}
/>
<br />
<br />
<Button type='submit' variant='contained'>
Submit
</Button>
</div>
);
};
const TextFieldComponent = (props) => {
const { name, label, size, variant, control } = props;
return (
<div>
<Controller
control={control}
name={name}
render={({ field: { onChange, onBlur, value, ref } }) => (
<TextField
label={label}
variant={variant}
size={size}
onBlur={onBlur}
onChange={onChange}
checked={value}
inputRef={ref}
/>
)}
/>
</div>
);
};

react-hook-form access to validation rules in nested component

I'd like to access to the validation rules defined in react-hook-form's Resister in the nested component to dynamically display required indicator(*).
Is there a way to access from Nested component?
I don't want to repeat by passing as a prop.
<TextBox ref={register({ required: true })} label="Serial No" name="serialNo" />
const TextBox = React.forwardRef(({ label, name }, ref) => (
<>
<label htmlFor={name}>
{label} {***required*** && <span>*</span>}
</label>
<input type="text" name={name} id={name} ref={ref} />
</>
))
have a look at https://react-hook-form.com/api#useFormContext
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 name="test" ref={register} />;
}
which allow you to access all hook form methods in the nested component level.

Use react-input-mask with antd in react-final-form

I would like to use react-input-mask with Ant Design Input in react-final-form. In order to use antd with react-final-form I also had to install redux-form-antd. So the file looks like this:
import React from "react";
import ReactDOM from "react-dom";
import { Button } from "antd";
import { Form, Field } from "react-final-form";
import InputMask from "react-input-mask";
import { TextField } from "redux-form-antd";
import "antd/dist/antd.css";
const onSubmit = async values => {
window.alert(JSON.stringify(values, 0, 2));
};
const Input = props => <InputMask {...props} />;
function App() {
return (
<Form
onSubmit={onSubmit}
render={({ handleSubmit, values }) => (
<form onSubmit={handleSubmit}>
<Field
name="mask"
parse={value =>
value
.replace(/\)/g, "")
.replace(/\(/g, "")
.replace(/-/g, "")
.replace(/ /g, "")
}
render={({ input, meta }) => (
<div>
<label>mask phone</label>
<Input mask="+7 (999) 999-99-99" {...input} />
{meta.touched && meta.error && <span>{meta.error}</span>}
</div>
)}
/>
<Field
name="antd"
component={TextField}
label="antd phone"
placeholder="Phone"
/>
<Button className="submit-button" type="primary">
Send
</Button>
<pre>{JSON.stringify(values, 0, 2)}</pre>
</form>
)}
/>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Here is a codesandbox example.
I could only get to work a regular input with an InputMask (input 1) or an antd input without a mask (input 2).
How can I add an InputMask to antd input?
I've managed to use react-input-mask with antd and react-final-form without any external libraries.
Here is my component:
import React from "react";
import InputMask from "react-input-mask";
import { Input } from "antd";
import FormItem from "antd/lib/form/FormItem";
const MaskInput = props => {
const { disabled, mask, label, meta, required } = props;
return (
<FormItem
label={label}
validateStatus={
meta.touched ? (meta.error ? "error" : "success") : undefined
}
help={meta.touched ? (meta.error ? meta.error : undefined) : undefined}
hasFeedback={meta.touched ? true : false}
required={required}
>
<InputMask
mask={mask}
disabled={disabled}
autoComplete="off"
{...props.input}
>
<Input />
</InputMask>
</FormItem>
);
};
export default MaskInput;
Then it is passed to the component prop of the Field:
<Field
name="phone"
label="Phone"
component={MaskInput}
mask="+7 (999) 999-99-99"
required
/>
Here is the link to the codesandbox example.
I've never used either of those libraries, but you might want to check out using format-string-by-pattern with react-final-form's built-in parsing and formatting functionality to achieve a similar thing.
I bet you could throw redux-form-antd components into here pretty easily...

Resources