Reputation: 1766
I have an input form that patches data. I would like the onSubmit function to send a render trigger to my useReducer that pulls data from my api get request and update my project with new data.
Right now the trigger is working but it's not causing a state re-render for the rest of the components. I know the trigger is working because of the successful api requests, but the new data is not showing up/
Here is the Parent component where the useReducer is. I then pass data from getFinData
ran inside the useEffect
to send data via state props to my Table component.
const initialState = {
loading: true,
error: '',
data: []
}
const reducer = (state, action) =>
{
switch (action.type)
{
case 'FETCH_SUCCESS':
return {
loading: false,
data: action.payload,
error: ''
}
case 'FETCH_ERROR':
return {
loading: false,
data: {},
error: "Something went wrong!"
}
default:
return state
}
}
export const Bucket = () => {
const [state, dispatch] = useReducer(reducer, initialState)
const { slug } = useParams();
useEffect(() =>
{
getFinData(dispatch)(slug);
console.log(state)
}, [])
return (
<>
<GetAboutBucketData /> //My input action lives deeply nested in GetAboutBucketData
<GetBucketData error={state.error} loading={state.loading} data={state.data}/>
</>
);
getFindData
is it's own function in a different file.
export const getFinData = (dispatch) => (slug) => axiosInstance
.get('bucket/fin-data/' + slug)
.then(response => {
dispatch({ type: 'FETCH_SUCCESS', payload: response.data })
console.log('fired')
})
.catch(error => {
dispatch({ type: 'FETCH_ERROR' })
})
Here is GetBucketData
:
function GetBucketData(props)
{
const {data, loading, error} = props
return (
<>
<Tables error={error} loading={loading} data={data}/>
</>
);
};
export default GetBucketData;
my input onSubmit
function where I want the request to cause a re-render for my useReducer.
const onSubmit = (data, e) =>
{
console.log(data);
axiosInstance
.patch(`bucket/add/symbols/` + slug + '/', {
stock_list: data.stock_list.map(list=>list.symbol),
})
.then((res) =>
{
getFinData(dispatch)(slug);
});
};
How can I get my useReducers state to cause a re-render?
Upvotes: 0
Views: 248
Reputation: 176
You could extract the logic of the useEffect to a function, call that function in the useEffect as well as pass it down to the form so it can be called inside the .then callback inside the onSubmit.
[UPDATE]
This is invalid as we have useReducer here from React not a Redux reducer.
You could extract the function to a separate file and provide dispatch with a higher order function. Keep in mind this is not the cleanest solution, lifting the state and fetch function up would be better.
//bucket-api.js
export const getFinData = (dispatch) => (slug) => axiosInstance
.get('bucket/fin-data/' + slug)
.then(response => {
dispatch({ type: 'FETCH_SUCCESS', payload: response.data })
})
.catch(error => {
dispatch({ type: 'FETCH_ERROR' })
})
Then in both files you would simply call it like this:
const dispatch = useDispatch();
getFinData(dispatch)(slug);
Upvotes: 1