【问题标题】:Why redux doesn't change state?为什么 redux 不改变状态?
【发布时间】:2020-12-07 08:27:51
【问题描述】:

我正在使用 Redux 构建一个简单的 React Native 应用程序。

这是我的初始状态

import { createStore } from "redux";
import reducer from "../reducers";

const initialState = {
  user: {
    uuid: null,
    bio: null,
    gender: null,
    full_name: null,
    cover_photo: null,
    profile_photo: null 
  },
  followers: {
    count: 0,
    list: null
  },
};

export const store = createStore(reducer, initialState);

动作

export const fetch_followers = (resp) => {
  return {
    type: FETCH_FOLLOWERS_SUCCESS,
    payload: resp
  }  
} 

减速器

import { 
  FETCH_FOLLOWERS_SUCCESS 
} from '../actions';

export default (state, action) => {
  switch(action.type){
    case FETCH_FOLLOWERS_SUCCESS:
      return {
        ...state,
        followers: {
          count: action.payload.profiles.length,
          list: action.payload.profiles
        }
      }
    default:
      return state
  }
}

api 包装器

class Client {
  constructor() {
    this.endpoints = {
        FETCH_MY_FOLLOWERS: 'https://run.mocky.io/v3/3d60da9d-1dd5-4e10-a69c-f2eefaa9a5da',
        FETCH_I_AM_FOLLOWING: 'https://run.mocky.io/v3/3d60da9d-1dd5-4e10-a69c-f2eefaa9a5da',

    }
  }

  followers() {
    return fetch(this.endpoints.FETCH_MY_FOLLOWERS).then(response => response.json());
  }

}

const client = new Client()
export default client;

我的视图组件

import React, { Component } from 'react';
import {SafeAreaView, ScrollView} from 'react-native';
import Follower from '../components/Follower'; 
import client from '../helpers/rabonia_sdk/RaboniaClient';
import { fetch_followers } from '../actions';
import { store } from '../store';



export default class Follow extends Component {
  constructor(){
    super()
  }

  componentDidMount() {
    client.followers().then(resp => {
        if(resp.status === "OK") {
          store.dispatch(fetch_followers(resp))
        }
    });
  }

  render() {
    return (
      <SafeAreaView>
        <ScrollView>
          {store.getState().followers.list.map(follower => <Follower follower={follower} /> )}
        </ScrollView>
      </SafeAreaView>
    );
  }
}

那一个是模拟 api 响应

{
  "status": "OK",
  "message": "Fetched",
  "profiles": [
   {"uuid": "a72ef52a-b814-4bc8-85ee-263621a6d96d", "full_name": "Michael Ballack", "profile_photo": "https://picsum.photos/200" },
   {"uuid": "a72ef52a-b814-4bc8-85ee-263621a6d96d", "full_name": "Patrice Evra", "profile_photo": "https://picsum.photos/200" },
   {"uuid": "a72ef52a-b814-4bc8-85ee-263621a6d96d", "full_name": "Dennis Bergkamp", "profile_photo": "https://picsum.photos/200" },
   {"uuid": "a72ef52a-b814-4bc8-85ee-263621a6d96d", "full_name": "Michael Owen", "profile_photo": "https://picsum.photos/200" }
  ]
}

其他组件的结构相同,它们可以正常工作。

当我切换到本地状态时(见下文),它可以工作,但无法确定将 api 有效负载分派到 redux 状态有什么问题?

export default class Follow extends Component {
  constructor(){
    super()
    this.state = {
      followers: []
    }
  }

  componentDidMount() {
    client.followers().then(resp => {
        if(resp.status === "OK") {
          this.setState({followers: resp.profiles});
          store.dispatch(fetch_followers(resp))
        }
    });
  }

  render() {
    let collection = store.getState().followers.list || this.state.followers
    return (
      <SafeAreaView>
        <ScrollView>
          {collection.map(follower => <Follower follower={follower} /> )}
        </ScrollView>
      </SafeAreaView>
    );
  }
}

【问题讨论】:

    标签: javascript react-native redux


    【解决方案1】:

    在 reducer 文件中,你必须为它分配你在顶部声明的 initialState

    export default (state = initialState , action) => {
      switch(action.type){
        case FETCH_FOLLOWERS_SUCCESS:
          return {
            ...state,
            followers: {
              count: action.payload.profiles.length,
              list: action.payload.profiles
            }
          }
        default:
          return state;
      }
    }
    

    【讨论】:

      【解决方案2】:

      Follow 组件在 Redux 中不是 connected,无论是使用 HOC 还是 useSelector。

      文档here

      例子:

      const mapStateToProps = (state) => ({
          followers: getFollowersListSelector(state),
      })
      
      
      export default connect(
          mapStateToProps,
          {}
      )(Follow)
      

      选择器:

      export const getFollowersSelector = state => state.followers
      
      export const getFollowersListSelector = state => getFollowersSelector(state).list
      

      并在render中使用它:

      this.props.followers.map(...)
      

      附注:您可以使用函数组件和 React 和 Redux Hooks 将代码保持在最低限度并使代码更具可读性。

      【讨论】:

        【解决方案3】:

        其他组件的结构相同,它们可以正常工作。

        在没有看到其他组件的情况下,不清楚您的确切含义,但您的商店未连接到此处的组件,这就是当 redux 状态更新时组件不会重新渲染的原因。

        在此处查看connect() 的文档:https://react-redux.js.org/api/connect

        【讨论】:

          猜你喜欢
          • 2020-01-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-30
          • 1970-01-01
          • 1970-01-01
          • 2019-02-20
          相关资源
          最近更新 更多