J'utilise useReducer dans mon fournisseur de contexte. L'idée est que je serai un lieu central pour mes fonctions d'état et d'expédition à vivre.

Je fais un appel axios à un datapase pour récupérer des projets. Cependant, lorsque je reviens dans la fonction de répartition, cela renvoie une promesse. Comment puis-je renvoyer les données de l'appel axios afin qu'il stocke les données de l'appel dans l'état ?

const initState = []

const projectsReducer = async (state, action) => {
    switch(action.type) {
        case 'FETCH_PROJECTS':
            const req = await axios.get('/api/fetch_projects')
            const { data } = req
            return {...state, data}
            
        default: 
            return state

    }
}

useEffect(() => {
    const initFetch = () => {
        projectsDispatch({type: 'FETCH_PROJECTS'})
    }
    initFetch()
}, [])


const [projects, projectsDispatch] = useReducer(projectsReducer, initState)
0
Mitchell Cartwright 17 oct. 2020 à 04:12

1 réponse

Meilleure réponse

Faites votre recherche dans l'effet, puis transmettez les données dans le réducteur.

Un réducteur est une fonction pure qui ne devrait pas avoir d'effets secondaires. De plus, toutes les données renvoyées par le réducteur sont définies comme état suivant. Ainsi, une fonction async retourne toujours une promesse - ce qui signifie que vous définissez l'état de projects pour être une promesse pour les données.

Si vous refactorisez votre code comme suit, cela devrait fonctionner.

const initState = {data: []};

const projectsReducer = (state, action) => {
    switch(action.type) {
        case 'FETCH_PROJECTS':
            const { data } = action.payload;
            return {...state, data}
            
        default: 
            return state

    }
}
const [projects, projectsDispatch] = useReducer(projectsReducer, initState)

useEffect(() => {
    const initFetch = async () => {
        const req = await axios.get('/api/fetch_projects')
        projectsDispatch({type: 'FETCH_PROJECTS', payload: {data: req.data}})
    }
    initFetch()
}, [])
// data is in projects.data;

Cependant, comme c'est plus simple, vous n'avez pas vraiment besoin d'un réducteur :

const [projects, setProjects] = useState([]);

useEffect(() => {
    const initFetch = async () => {
        const req = await axios.get('/api/fetch_projects')
        setProjects(req.data);
    }
    initFetch()
}, [])
// data is in projects
1
Zachary Haber 17 oct. 2020 à 03:06