反应本机:useSelector Redux为空

时间:2020-01-01 06:28:31

标签: react-native react-redux react-native-android

我是新手,我想使用react native来创建android应用程序,因此在创建项目后,我安装了redux和redux thunk并进行了redux想工作的所有配置。

我创建一个动作文件:

export const GETSURVEYOR = 'GETSURVEYOR';

const URL = "http://192.168.1.6:3000/";

export const fetchSurveyor = () => {
    return async dispatch => {
        const controller = new AbortController();
        const timeout = setTimeout(
            () => { controller.abort(); },
            10000,
        );
        const response = await fetch(`${URL}GetSurveyorList`,
            {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({}),
                signal: controller.signal
            });
        clearTimeout(timeout);
        const resData = await response.json();

        dispatch({
            type: GETSURVEYOR,
            surveyorList: resData.SurveyorList
        });
    }
}

之后,我创建了reducer来处理此数据:

import {GETSURVEYOR} from '../actions/surveyor'

const initialState = {
    surveyorList: []
}

export default (state = initialState, action) => {
    switch (action.type) {
        case GETSURVEYOR:
            return {
                ...state,
                surveyorList: action.surveyorList
            };

现在我正在使用useSelector, useDispatch中的'react-redux

import React, { useState, useEffect, useCallback } from 'react';
import { useSelector, useDispatch } from 'react-redux';

import * as surveyorActions from '../store/actions/surveyor';

export default () => {
    const [surveyorCount, setSurveyorCount] = useState(0);
    const survayers = useSelector(state => state.surveyor.surveyorList);
    const dispatch = useDispatch();


    const loadSurvayer = useCallback(async () => {
        await dispatch(surveyorActions.fetchSurveyor());
        console.log('run use Callback');
        console.log('returned :', survayers );
        // setSurveyorCount(survayers.length);
    }, [dispatch]);

    useEffect(() => {
        loadSurvayer();
    }, [dispatch]);

    return [loadSurvayer, surveyorCount];
}

第一次呈现此分页时,survayers当然是空的,但是在获取了有效的数据并将状态设置为reducer后,survayers螺母为空。 但是我还是空着吗?我确定数据是从服务中获取的,但是我从survayers那里空了吗?

LOG  Running "RNAuditMngm" with {"rootTag":1}
 LOG  run use Callback
 LOG  returned : []
 LOG  run use Callback
 LOG  returned : []

如果我将useEffect代码更改为此:

useEffect(() => {
    loadSurvayer();
}, [dispatch,survayers]);

我跌倒了!我该如何更改代码而没有循环?

2 个答案:

答案 0 :(得分:1)

我认为一切正常,但是您没有在正确的位置使用console.log。运行loadSurvayer时,survayers为空。即使是第二次也为空,因为您没有将其作为依赖项传递给useEffect挂钩。就像您说的那样,如果将其作为依赖项传递,则会导致无限循环,这是正确的,因为只要survayers发生更改,该函数就会被再次调用,依此类推。

所以,这是您必须做的:

  1. 从您的dispatch钩子中删除useEffect依赖项。
  2. console.log函数外部更改loadSurvayer的位置。
  3. await调用中删除dispatch,因为它是同步的。

以下是修改代码以使其正常工作的方法:

import React, { useState, useEffect, useCallback } from 'react';
import { useSelector, useDispatch } from 'react-redux';

import * as surveyorActions from '../store/actions/surveyor';

export default () => {
    const [surveyorCount, setSurveyorCount] = useState(0);
    const survayers = useSelector(state => state.surveyor.surveyorList);
    const dispatch = useDispatch();


    const loadSurvayer = useCallback(async () => {
        dispatch(surveyorActions.fetchSurveyor()); // Remove the `await`
        console.log('run use Callback');
        // setSurveyorCount(survayers.length);
    }, [dispatch]);

    useEffect(() => {
        loadSurvayer();
    }, []); // <-- remove the `dispatch` from here.

    console.log('returned :', survayers ); // <-- Move the console log here

    return [loadSurvayer, surveyorCount];
}

改进建议:建议删除surveyorCount状态变量,因为实际上并不需要它,因为您可以直接返回计数。

import React, { useState, useEffect, useCallback } from 'react';
import { useSelector, useDispatch } from 'react-redux';

import * as surveyorActions from '../store/actions/surveyor';

export default () => {
    // Remove the `surveyorCount`
    //const [surveyorCount, setSurveyorCount] = useState(0);
    const survayers = useSelector(state => state.surveyor.surveyorList);
    const dispatch = useDispatch();


    const loadSurvayer = useCallback(async () => {
        dispatch(surveyorActions.fetchSurveyor()); // Remove the `await`
        console.log('run use Callback');
        // setSurveyorCount(survayers.length);
    }, [dispatch]);

    useEffect(() => {
        loadSurvayer();
    }, []); // <-- remove the `dispatch` from here.

    console.log('returned :', survayers ); // <-- Move the console log here

    //return [loadSurvayer, surveyorCount];
    return [loadSurvayer, survayers.length]; // <-- Use `survayers.length` instead of `surveyorCount`
}

答案 1 :(得分:0)

在useSelector中,您不应该这样阅读state.surveyorList吗?您所在的州没有任何名为Surveyor的对象,但是您当前正在阅读类似state.surveyor.surveyorList