重构React代码,以使用Firebase RT数据库和Redux Hooks中的Redux状态

我是尼尔

我一直在使用以前使用的集成Redux和Firebase数据库的样板来设置网站/ React App。但是,我是第一次在使用此样板的项目中使用React Hooks。到目前为止,我从Firebase RT-DB提取数据并将其与useState和useEffect一起使用都没有问题。现在,我想重构代码以将应用程序的状态存储在Redux中,但仍然使用功能组件并利用Hooks。

我很难将所有内容放在一起。

目前,我的设置如下所示:我不对Firebase中的任何数据进行身份验证,而直接将数据拉入。我已经包含了我的主页组件作为示例,该组件具有来自Firebase db的2个状态/数据的基本部分} & {姓}。

为了澄清我的问题,我在从动作生成器内部的实时数据库中获取数据,然后将其分派给reducer函数时遇到了麻烦。

我已经包括了我认为动作应该是什么样的,但是我不确定这是正确的,然后是reducer函数应该是什么样的。

任何帮助,不胜感激。

app.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { store } from './store/configureStore';
import AppRouter, { history } from './routers/AppRouter';

// const store = configureStore();

const jsx = (
  <Provider store={store}>
    <AppRouter history={history} />
  </Provider>

);

ReactDOM.render(jsx, document.getElementById('app')); 

configureStore.js

import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';

export const reducers = combineReducers({

});

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

// store.js

export function configureStore(initialState = {}) {

  const store = createStore(reducers, initialState, composeEnhancers(applyMiddleware(thunk)), window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());

  return store;
}

export const store = configureStore();

homepage.js组件示例

import React, { useState, useEffect } from "react";
import database from '../firebase/firebase';

const HomePage = () => {

    const [firstName, setFirstName] = useState(firstName);
    const [lastName, setLastName] = useState(lastName);

    useEffect(() => {
        database.ref()
            .once('value')
            .then((snapshot) => {
                const data = snapshot.val();
                const { firstName, lastName } = data
                setFirstName(firstName)
                setLastName(lastName)
            })
            .catch((e) => {
                console.log('Error fetching data', e);
            });
    }, []);

    return (
         <div className="homepage-section__content">
            <HomePageTitle firstName={firstName} lastName={lastName} />
         </div>
    )
}

export { HomePage as default };

homePageTitle.js组件

import React from 'react';

const HomePageTitle = (props) => (
    <React.Fragment>
        <h1>
            {props.firstName}
            <span>{props.lastName}</span>
        </h1>
    </React.Fragment>
);

export { HomePageTitle as default };

德鲁·里斯(Drew Reese)

以下是移植本地组件状态并useEffect回调到redux状态和操作的一种方法。

您可以定义一组数据获取启动,成功和失败操作。

const setDataLoading = loading => ({
  type: "FETCH_DATA_LOADING",
  payload: loading,
});

const fetchDataSuccess = payload => ({
  type: "FETCH_DATA_SUCCESS",
  payload, // { firstName, lastName }
});

const fetchDataFailure = () => ({ type: "FETCH_DATA_FAILURE" });

const fetchData = () => dispatch => {
  dispatch(setDataLoading(true)); // <-- start loading
  return database.ref() // <-- return Promise chain
    .once('value')
    .then((snapshot) => {
      const { firstName, lastName } = snapshot.val();
      dispatch(fetchDataSuccess({ firstName, lastName }));
    })
    .catch((e) => {
      console.error('Error fetching data', e);
      dispatch(fetchDataFailure());
    })
    .finally(() => dispatch(setDataLoading(false))); // <-- complete loading
};

定义您的减速器。FETCH_DATA操作将启动异步操作以获取数据,清除任何当前错误状态并将其设置loading为true。成功或失败后,将清除加载状态,并存储名称数据或设置错误值。

const initialState = {
  error: false,
  loading: false,
  firstName: null,
  lastName: null,
};

const reducer = (state = initialState, action) => {
  switch(action.type) {
    case "FETCH_DATA_LOADING":
      return {
        ...state,
        loading: action.payload,
      };

    case "FETCH_DATA_SUCCESS":
      return {
        ...state,
        error: false,
        ...action.payload, // ...{ firstName, lastName }
      };

    case "FETCH_DATA_FAILURE":
      return {
        ...state,
        error: true,
      };

    default:
      return state;
  }
};

将减速器添加到存储中。

import userReducer from './path/to/reducer/above';

const reducers = combineReducers({
  user: userReducer,
});

连线HomePage至Redux商店。

const HomePage = () => {
  const dispatch = useDispatch();
  const { error, firstName, lastName, loading } = useSelector(state => state.user);

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

  return (
    <div className="homepage-section__content">
      {error && <div>Error fetching user name</div>}
      {loading ? (
        <LoadingSpinner />
      ) : (
        <HomePageTitle firstName={firstName} lastName={lastName} />
      )}
    </div>
  )
};

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

React Redux Hooks找不到状态

React + Redux中的路由状态名称

使用重新基准在React app和Firebase数据库之间同步状态的多个属性

等待操作更新react-native和redux中的状态

mapStateToProps中的状态是JSX!React / Redux

保存到数据库后,React Redux存储状态更新过程

react-redux-firebase:实时数据库中未定义的uid

如何从React Redux中查找/过滤状态

如果所有数据都在ajax请求或数据库中,请使用redux

使用reducer更新Redux中的特定状态

如何通过React Hooks使用Redux状态

在React Redux中管理UI状态

如何在Firebase和Firestore作为数据库之间动态切换并相应地调度redux操作

当React Hooks中的redux状态更改时,道具不更新

当数据在Redux中时使用表单的本地状态

Redux Store不会使用Firebase实时数据库上的已创建数据更新状态

无法从redux接收react组件中的状态

无法使用React Hooks读取Redux中的状态,无法读取null的属性'_id'

如何在React Actions Redux中获取状态数据?

我如何从React中的Redux状态中提取数据

如何使用Redux和React从数据库中获取单个数据元素?

React和Redux:在Redux中存储加载状态的正确方法

React / Redux:在数据库中创建记录并访问新创建的记录

组件中的 React-Redux 状态与 store 中的状态不同

如何在 react-native/redux 中处理外部数据库更新?

使用 Redux 更新组件状态以查看 Flatlist 中的数据

如何使用 Redux 定期更新和 React Hooks 处理状态?

如何更新 React Redux 中的状态?

从 React 中从 redux 读取的数据更新状态