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;
Related
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?
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>
);
}
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}
/>
)
})
Hello I got stuck during creating app using hooks
I do not why but my Component does not download a state from my Context Component or maybe my initial state does not update correctly. Does somebody have any idea what's going on?
Context Component:
import React, { createContext, useState } from 'react';
export const WeatherDataContext = createContext();
const WeatherDataContextProvider = (props) => {
const [weather, setWeather] = useState(
{
city: null,
temp: null
}
)
const addWeather = (city, temp) => {
setWeather({
city,
temp
})
}
return (
<WeatherDataContext.Provider value={{weather, addWeather}}>
{props.children}
</WeatherDataContext.Provider>
)
}
export default WeatherDataContextProvider
Form - axios - Component:
import React, {useContext, useState} from 'react';
import { WeatherDataContext } from '../context/WeatherDataContext';
import axios from 'axios'
import {Link} from 'react-router-dom'
const WeatherForm = () => {
const {addWeather} = useContext(WeatherDataContext);
const [value, setValue] = useState('')
const handleChange = (e) => {
e.preventDefault();
axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${value}&appid=${KEY}&units=metric`)
.then(res => {
addWeather(res.data.name, res.data.main.temp)
})
}
return (
<div class='weather-form'>
<form onSubmit={handleChange}>
<input placeholder='City' onChange={(e) => setValue(e.target.value)} value={value} required/>
<Link to='/weather'><button>Search</button></Link>
</form>
</div>
)
}
export default WeatherForm
And final component where I want to use my update state
import React, {useContext, useState} from 'react';
import { WeatherDataContext } from '../context/WeatherDataContext';
const WeatherFront = () => {
const {weather} = useContext(WeatherDataContext)
console.log(weather)
return (
<div class='weather-front'>
<h1>City: {weather.city}, Temperatura: {weather.temp}</h1>
</div>
)
}
export default WeatherFront
Your button is not submitting the form - it navigates away from the page instead.
So handleChange is not being called.
You can call it from buttons onClick instead of forms onSubmit. Be sure to omit e.preventDefault() then, so that parent Link can still navigate.
const WeatherForm = () => {
const { addWeather } = useContext(WeatherDataContext)
const [value, setValue] = useState('')
const handleChange = (e) => {
axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${value}&appid=${KEY}&units=metric`)
.then(res => {
addWeather(res.data.name, res.data.main.temp)
})
}
return (
<div class="weather-form">
<form >
<input
placeholder="City"
onChange={(e) => setValue(e.target.value)}
value={value}
required
/>
<Link to="/weather">
<button onClick={handleChange}>Search</button>
</Link>
</form>
</div>
)
}
Be sure to wrap both pages inside the same context:
<WeatherDataContextProvider>
<Router>
<Switch>
<Route path="/weather">
<WeatherFront></WeatherFront>
</Route>
<Route path="/">
<WeatherForm></WeatherForm>
</Route>
</Switch>
</Router>
</WeatherDataContextProvider>
I'm building app, using hooks and I got stuck.
I do not why but my Component does not download a state from my Context Component or maybe my initial state does not update correctly. Bellow I insert a few screenshot from my app.
Context Component:
import React, { createContext, useState } from 'react';
export const WeatherDataContext = createContext();
const WeatherDataContextProvider = (props) => {
const [weather, setWeather] = useState(
{
city: null,
temp: null
}
)
const addWeather = (city, temp) => {
setWeather({
city,
temp
})
}
return (
<WeatherDataContext.Provider value={{weather, addWeather}}>
{props.children}
</WeatherDataContext.Provider>
)
}
export default WeatherDataContextProvider
Form - axios - Component:
import React, {useContext, useState} from 'react';
import { WeatherDataContext } from '../context/WeatherDataContext';
import axios from 'axios'
import {Link} from 'react-router-dom'
const WeatherForm = () => {
const {addWeather} = useContext(WeatherDataContext);
const [value, setValue] = useState('')
const handleChange = (e) => {
e.preventDefault();
axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${value}&appid=${KEY}&units=metric`)
.then(res => {
addWeather(res.data.name, res.data.main.temp)
})
}
return (
<div class='weather-form'>
<form onSubmit={handleChange}>
<input placeholder='City' onChange={(e) => setValue(e.target.value)} value={value} required/>
<Link to='/weather'><button>Search</button></Link>
</form>
</div>
)
}
export default WeatherForm
And final component where I want to use my update state
import React, {useContext, useState} from 'react';
import { WeatherDataContext } from '../context/WeatherDataContext';
const WeatherFront = () => {
const {weather} = useContext(WeatherDataContext)
console.log(weather)
return (
<div class='weather-front'>
<h1>City: {weather.city}, Temperatura: {weather.temp}</h1>
</div>
)
}
export default WeatherFront
The problem may be that you are not submitting the form.
<Link to='/weather'><button>Search</button></Link>
just navigates to WeatherFront.
You may try
import { useHistory } from "react-router-dom";
...
const WeatherForm = () => {
const history = useHistory()
const {addWeather} = useContext(WeatherDataContext)
const [value, setValue] = useState('')
const handleChange = (e) => {
e.preventDefault();
axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${value}&appid=${KEY}&units=metric`)
.then(res => {
addWeather(res.data.name, res.data.main.temp)
history.push('/weather')
})
}
return (
<div class='weather-form'>
<form onSubmit={handleChange}>
<input placeholder='City' onChange={(e) => setValue(e.target.value)} value={value} required/>
<input type="submit" value="Search" />
</form>
</div>
)
}