Cannot read property 'focus' of null error when extracting component - reactjs

I would like to implement Algolia search with Ant Design Autocomplete. But I get Cannot read property 'focus' of null error when I try to extract the SearchInput component (without extraction, i. e. when I leave it in the same file, it works fine). Here is the working code:
import React, { useState } from 'react'
import { AutoComplete, Input } from 'antd'
const SearchAutocomplete = connectAutoComplete(
({ hits, currentRefinement, refine }) => {
...
return (
<AutoComplete
options={options}
onSelect={onSelect}
onSearch={handleSearch}
open={open}
>
<Input
value={currentRefinement}
onChange={e => refine(e.currentTarget.value)}
/>
</AutoComplete>
);
}
);
But when I move Input to a separate component like this it doesn't work:
import React, { useState } from 'react'
import { AutoComplete } from 'antd'
import SearchInput from './SearchInput'
const SearchAutocomplete = connectAutoComplete(
({ hits, currentRefinement, refine }) => {
...
return (
<AutoComplete
options={options}
onSelect={onSelect}
onSearch={handleSearch}
open={open}
>
<SearchInput value={currentRefinement} onChange={e => refine(e.currentTarget.value)}/>
</AutoComplete>
);
}
);
And the SearchInput component itself:
import React from 'react'
import { Input } from 'antd'
const SearchInput = props => {
const { value, onChange} = props;
return (
<Input
value={value}
onChange={onChange}
/>
)
}
Here is the link to codesandbox with the extracted component. How can I fix this error?

Adding React.forwardRef() to SearchInput solved the issue:
const SearchInput = React.forwardRef((props, ref) => {
const { onChange } = props;
return (
<Input.Search
onChange={onChange}
ref={ref}
/>
)
})

Related

using Redux form, working with react-select,integrating with redux-form, but handle submit is not working

i am working on Select feature, where i need to select a value from the select field. i am using redux-form, and working with react-select and integrating with redux-form. when i select a option from the list of option, handleSubmit function is not being triggred. below is the code snippet of react-form -Field implementation
import React from "react";
import { Field, reduxForm } from "redux-form";
import ReduxFormSelect from "./ReduxFormSelect";
const SelectInputField = (props) => {
const { userOptions, handleSubmit, name } = props;
return (
<form onSubmit={handleSubmit}>
<Field
name={name}
component={ReduxFormSelect}
sytle={styles.selectInput}
options={userOptions}
/>
</form>
);
};
export default reduxForm({
form: "wizard",
initialValues: {
FilterFor: {
label: "correct",
value: "correct",
},
},
})(SelectInputField);
below is the code where i am using Select component from react-select integrating the input field
generated by redux-form -- ReduxFormSelect component
import React from "react";
import Select from "react-select";
const ReduxFormSelect = (props) => {
const { input, options } = props;
return (
<Select
{...input}
onChange={(value) => {
input.onChange(value);
}}
onBlur={() => input.onBlur(input.value)}
options={options}
/>
);
};
export default ReduxFormSelect;
below is where the handleSubmit function is sent as props to SelectInputComponent, where this handleSubmit function is not being triggered, when one of the options being changed
import React, { Fragment } from "react";
import { Container, Row, Col } from "react-bootstrap";
import { connect } from "react-redux";
import { reduxForm } from "redux-form";
import { filteredResultsAction } from "../../Actions";
import SelectInputField from "../reusableComponents/SelectInputField";
import ShowFilteredResults from "./ShowFilteredResults";
const ShowAttemptedQue = (props) => {
const { ans, opt_values } = props;
const handleSubmit = (values) => {
console.log("changed option values",values);
};
return (
<Fragment>
<Container>
<Row>
<Col>Attempted Questions:</Col>
<Col md="auto">
Filted By :{" "}
<SelectInputField
name="filterFor"
userOptions={opt_values}
handleSubmit={handleSubmit}
/>
</Col>
</Row>
<ShowFilteredResults result_data={ans} />
</Container>
</Fragment>
);
};
const mapStateToProps = (state) => {
return {
ans: state.updatedTempVal.attempted,
opt_values: state.updatedTempVal.options,
};
};
export default connect(mapStateToProps, { filteredResultsAction })(
ShowAttemptedQue
);
where am i going wrong?

problems with final-form in React

I have some problems with final-form. function handleSubmit don't calls anything. I checked official final-form example. I do identically that written there. But it's not working.
Here my form code:
import React, {FunctionComponent} from 'react';
import {Field, Form} from 'react-final-form';
import {IAddComponentProps} from "./interfaces";
import {EditContainer, StyledButton} from './styles';
import EditInput from "../EditInput";
const AddComponent: FunctionComponent<IAddComponentProps> = ({onSubmitForm, onEditInput}) => {
return (
<Form
onSubmit={onSubmitForm}
render={({handleSubmit}) => (
<EditContainer onSubmit={handleSubmit}>
<Field name={'addComment'}>
{({input}) => (
<EditInput {...input} onEditInput={onEditInput}/>
)}
</Field>
<StyledButton>OK</StyledButton>
</EditContainer>
)}
/>
)
};
export default AddComponent;
Here is my functions which I put into props:
const onChangeInput = (event: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(event.target.value)
}
const onSubmitAddComment = (event: React.ChangeEvent<HTMLFormElement>) => {
const newComment: ICommentsData = {
id: new Date().getMilliseconds(),
cardId: cardId,
name: author,
comment: inputValue
}
event.preventDefault();
event.target.reset()
dispatch(actions.comments.addComment({newComment}))
resetInputValue()
}
The reason of this was, that i put into onSubmit of Form function from props. When i created function inside component it started working. So new code of my form is:
import React, {FunctionComponent} from 'react';
import {Field, Form} from 'react-final-form';
import {IAddComponentProps} from "./interfaces";
import {EditContainer, StyledButton} from './styles';
import EditInput from "../EditInput";
const AddComponent: FunctionComponent<IAddComponentProps> = ({onSubmitForm, onEditInput}) => {
const onSubmit = () => {
onSubmitForm()
}
return (
<Form
onSubmit={onSubmit}
render={({handleSubmit,form}) => (
<EditContainer onSubmit={(event) => {
event.preventDefault()
handleSubmit()
form.reset()
}}>
<Field name={'addComment'}>
{({input}) => (
<EditInput {...input} onEditInput={onEditInput}/>
)}
</Field>
<StyledButton>OK</StyledButton>
</EditContainer>
)}
/>
)
};
export default AddComponent;

how to extract data from react components in a loop?

I have a bunch of filtering components that developers can use. For example TextFilter.js, OptionsFilter.sj, NumericFilter.js
And this is the code of TextFilter.js
import TextField from '#material-ui/core/TextField';
import { useState } from 'react';
const TextFilter = ({ column, placeholder }) => {
const [value, setValue] = useState('');
return <TextField
onChange={(event, value) => setValue(event.target.value)}
lable={placeholder}
/>
};
export default TextFilter;
Developers use it this way:
import List from '../../Components/Layouts/List';
import TextFilter from '../../Components/Filters/TextFilter';
import NumericFilter from '../../Components/Filters/NumericFilter';
const filters =
<>
<TextFilter column='title' placeholder='Title' />
<NumericFilter column='age' placeholder='Age' min={20} max={130} />
</>
cons SampleList = (props) => {
return (
<ListComponent
filters={filters}
/>
);
};
Now I'm stuck on how to extract values from these filters. How can I extract values?
You should handle child's value in it's parent:
child:
import TextField from "#material-ui/core/TextField";
const TextFilter = ({ column, placeholder, changed }) => {
return (
<TextField
onChange={(event) => changed(event.target.value)}
placeholder={placeholder}
/>
);
};
export default TextFilter;
parent:
import TextFilter from "./TextFilter";
export default function App() {
const handleChanged = (value) => {
console.log(value);
};
return (
<div className="App">
<TextFilter
column="title"
placeholder="Title"
changed={(value) => handleChanged(value)}
/>
</div>
);
}

React Suite Accepter Component Not Updating Form Value On Change

I am using rsuitejs for components, and in a form I am creating I have a custom slider called MotivationSlider which isn't updating the data in the form it's in when the value is changed. The custom Slider looks like this:
import React, { useState } from 'react';
import { Slider } from 'rsuite';
const MotivationSlider = () => {
const [motivation, setMotivation] = useState(2);
return (
<Slider
min={0}
max={4}
value={motivation}
graduated
progress
className="custom-slider"
onChange={v => setMotivation(v)}
renderMark={mark => {
if ([0, 4].includes(mark)) {
return <span>{mark === 0 ? 'Not Very' : 'Highly!'}</span>;
}
return null;
}}
/>
);
};
export default MotivationSlider;
It is wrapped in a Custom Field which looks like this:
// CustomField.js:
import React from 'react';
import { FormGroup, ControlLabel, FormControl, HelpBlock } from 'rsuite';
const CustomField = ({ name, message, label, accepter, error, ...props }) => {
return (
<FormGroup className={error ? 'has-error' : ''}>
<ControlLabel>{label} </ControlLabel>
<FormControl
name={name}
accepter={accepter}
errorMessage={error}
{...props}
/>
<HelpBlock>{message}</HelpBlock>
</FormGroup>
);
};
export default CustomField;
// FormPage.js:
<CustomField
accepter={MotivationSlider}
name="motivation"
/>
When I change the slider value, the form data does not change, however if I use the CustomField with a normal Slider like this, the form value does change.
<CustomField
accepter={Slider}
name="motivation"
min={0}
max={4}
/>
What am I doing wrong here?
Form custom controls need to implement the attributes onChange, value, and defaultValue.
import React, { useState } from "react";
import { Slider } from "rsuite";
const MotivationSlider = React.forwardRef((props, ref) => {
const { value: valueProp, defalutValue, onChange } = props;
const [motivation, setMotivation] = useState(defalutValue);
const value = typeof valueProp !== "undefined" ? valueProp : motivation;
return (
<Slider
ref={ref}
min={0}
max={4}
value={value}
graduated
progress
className="custom-slider"
onChange={(v) => {
onChange(v);
setMotivation(v);
}}
renderMark={(mark) => {
if ([0, 4].includes(mark)) {
return <span>{mark === 0 ? "Not Very" : "Highly!"}</span>;
}
return null;
}}
/>
);
});
export default MotivationSlider;

Formik with react-naitve, using useField?

I don't use formik's Field with react-native
because doc says <Field /> will default to an HTML <input /> element
I'd like to use useField (https://stackoverflow.com/a/58650742/433570)
and wonder useField is usable with react-native?
import React from "react";
import { useField, useFormikContext } from "formik";
import DatePicker from "react-datepicker";
export const DatePickerField = ({ ...props }) => {
const { setFieldValue } = useFormikContext();
const [field] = useField(props);
return (
<DatePicker
{...field}
{...props}
selected={(field.value && new Date(field.value)) || null}
onChange={val => {
setFieldValue(field.name, val);
}}
/>
);
};

Resources