Javascript 动作分派后呈现组件

Javascript 动作分派后呈现组件,javascript,reactjs,redux,Javascript,Reactjs,Redux,在页面加载时,我在index.js中调度一个actionstore.dispatch(getWeatherReports())点击天气API。此操作经过redux过程,最终将返回的数据添加到名为weatherReports的状态的属性中。此属性是具有空数组的对象。现在,我将粘贴代码概述。。并非所有这些都是为了省去逐行操作的麻烦,因为从API输出数据并不是我的问题 这是我的index.js: import 'babel-polyfill'; import React from 'react'; i

在页面加载时,我在
index.js
中调度一个action
store.dispatch(getWeatherReports())点击天气API。此操作经过
redux
过程,最终将返回的数据添加到名为
weatherReports
的状态的属性中。此属性是具有空数组的对象。现在,我将粘贴代码概述。。并非所有这些都是为了省去逐行操作的麻烦,因为从API输出数据并不是我的问题

这是我的
index.js

import 'babel-polyfill';
import React from 'react';
import {render} from 'react-dom';
import configureStore from './store/configureStore';
import {Provider} from 'react-redux';
import {Router, browserHistory} from 'react-router';
import {StyleRoot} from 'radium';
import routes from './routes';
import {loadBlogs} from './actions/blogActions';
import {loadUsers, getActiveUser} from './actions/userActions';
import {getWeatherReports} from './actions/weatherActions';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import '../node_modules/toastr/build/toastr.min.css';
import './styles/app.scss';

const store = configureStore();
store.dispatch(loadBlogs());
store.dispatch(loadUsers());
store.dispatch(getActiveUser());
store.dispatch(getWeatherReports());

render(
  <StyleRoot>
    <Provider store={store}>
      <Router history={browserHistory} routes={routes}/>
    </Provider>
  </StyleRoot>,
  document.getElementById('app')
);
import React, {PropTypes} from 'react';
import styles from '../common/contentBoxStyles';

const WeatherReport = ({reports}) => {
    console.log(reports);
    return (
        <div style={styles.body} className="row">
            <div style={styles.weatherBoxContainer}>
                <div className="col-sm-2 col-md-offset-1" style={styles.weatherBoxContainer.weatherCard}>
                    <div style={styles.weatherBoxContainer.weatherReport}>
                        <div style={styles.weatherBoxContainer.currentTemp}>
                            HERE IS MY PROBLEM!!
                            {reports[0].main.temp}
                        </div>
                    </div>
                    CA
                </div>
                <div className="col-sm-2" style={styles.weatherBoxContainer.weatherCard}>
                    <div style={styles.weatherBoxContainer.weatherReport}>
                        Report
                    </div>
                    UT
                </div>
                <div className="col-sm-2" style={styles.weatherBoxContainer.weatherCard}>
                    <div style={styles.weatherBoxContainer.weatherReport}>
                        Report
                    </div>
                    MN
                </div>
                <div className="col-sm-2" style={styles.weatherBoxContainer.weatherCard}>
                    <div style={styles.weatherBoxContainer.weatherReport}>
                        Report
                    </div>
                    DC
                </div>
                <div className="col-sm-2" style={styles.weatherBoxContainer.weatherCard}>
                    <div style={styles.weatherBoxContainer.weatherReport}>
                        Report
                    </div>
                    NY
                </div>
            </div>
        </div>
    );
};

WeatherReport.propTypes = {
    reports: PropTypes.array
};

export default WeatherReport;
同样,请相信我有适当的
MapStateTrops
mapDispatchToProps
,等等。然后我会在
dumb
组件中显示数据<代码>WeatherReport.js

import 'babel-polyfill';
import React from 'react';
import {render} from 'react-dom';
import configureStore from './store/configureStore';
import {Provider} from 'react-redux';
import {Router, browserHistory} from 'react-router';
import {StyleRoot} from 'radium';
import routes from './routes';
import {loadBlogs} from './actions/blogActions';
import {loadUsers, getActiveUser} from './actions/userActions';
import {getWeatherReports} from './actions/weatherActions';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import '../node_modules/toastr/build/toastr.min.css';
import './styles/app.scss';

const store = configureStore();
store.dispatch(loadBlogs());
store.dispatch(loadUsers());
store.dispatch(getActiveUser());
store.dispatch(getWeatherReports());

render(
  <StyleRoot>
    <Provider store={store}>
      <Router history={browserHistory} routes={routes}/>
    </Provider>
  </StyleRoot>,
  document.getElementById('app')
);
import React, {PropTypes} from 'react';
import styles from '../common/contentBoxStyles';

const WeatherReport = ({reports}) => {
    console.log(reports);
    return (
        <div style={styles.body} className="row">
            <div style={styles.weatherBoxContainer}>
                <div className="col-sm-2 col-md-offset-1" style={styles.weatherBoxContainer.weatherCard}>
                    <div style={styles.weatherBoxContainer.weatherReport}>
                        <div style={styles.weatherBoxContainer.currentTemp}>
                            HERE IS MY PROBLEM!!
                            {reports[0].main.temp}
                        </div>
                    </div>
                    CA
                </div>
                <div className="col-sm-2" style={styles.weatherBoxContainer.weatherCard}>
                    <div style={styles.weatherBoxContainer.weatherReport}>
                        Report
                    </div>
                    UT
                </div>
                <div className="col-sm-2" style={styles.weatherBoxContainer.weatherCard}>
                    <div style={styles.weatherBoxContainer.weatherReport}>
                        Report
                    </div>
                    MN
                </div>
                <div className="col-sm-2" style={styles.weatherBoxContainer.weatherCard}>
                    <div style={styles.weatherBoxContainer.weatherReport}>
                        Report
                    </div>
                    DC
                </div>
                <div className="col-sm-2" style={styles.weatherBoxContainer.weatherCard}>
                    <div style={styles.weatherBoxContainer.weatherReport}>
                        Report
                    </div>
                    NY
                </div>
            </div>
        </div>
    );
};

WeatherReport.propTypes = {
    reports: PropTypes.array
};

export default WeatherReport;
import React,{PropTypes}来自'React';
从“../common/contentBoxStyles”导入样式;
const WeatherReport=({reports})=>{
控制台日志(报告);
返回(
这是我的问题!!
{报告[0].main.temp}
加利福尼亚州
报告
美国犹他州
报告
锰
报告
直流
报告
纽约
);
};
WeatherReport.propTypes={
报告:PropTypes.array
};
导出默认天气报告;
我的根本问题是在分派操作返回数据之前。。我正试图通过
dumb
组件渲染它。因此,我在尝试访问数据时收到以下错误:
uncaughttypeerror:执行以下操作时无法读取未定义(…)的属性“main”。
报告[0]。main.temp 发生的事情是,这阻止了我的应用程序向前移动,因此
store.dispatch(getWeatherReports())从不被调用。因此,如果我从等式中删除
{reports[0].main.temp}
,那么该过程将继续并调度该操作。然后我可以把方程称为w/HMR和hooray!!数据就在那里


因此,我的问题,也感谢您的支持,是我如何才能得到它,使我的哑组件等待尝试并访问状态上的这些属性,直到我的初始调度操作发生之后?

在尝试访问
.main
之前,检查
报告[0]
是否存在。如果
未定义
,则显示加载微调器或其他内容

 if (!reports[0]) return <div>Loading...</div>

 return (
   // your component like normal.
 )
if(!reports[0])返回加载。。。
返回(
//你的部件和正常的一样。
)

如果getWeatherReports请求是由支持承诺的东西发出的,而不是通过回调通知您成功响应的东西(即类似的东西),那么您可以尝试使用类似于redux promise的中间件

redux promise将拦截分派操作,并在承诺未解决的情况下阻止其将操作转发给商店的订户

一旦您获得成功的响应并且承诺得到解决,中间件将创建一个新操作,该操作的操作类型与原始操作相同,但负载包含您需要的数据

您可以按如下方式使用它:

import { createStore, applyMiddleware } from 'redux';
import promise from 'redux-promise'; 

const store = configureStore();
store.dispatch(loadBlogs());
...
...
store.dispatch(getWeatherReports());

const storeWithMiddleWare = applyMiddleware(promise)(store);

似乎
store.dispatch(getWeatherReports())
是一个异步API调用。因此,在DOM中呈现组件之前,需要等待响应

解决方法:使用

要点:

import { createStore, applyMiddleware } from 'redux';
import promise from 'redux-promise'; 

const store = configureStore();
store.dispatch(loadBlogs());
...
...
store.dispatch(getWeatherReports());

const storeWithMiddleWare = applyMiddleware(promise)(store);
  • 它允许您请求异步数据,将它们存储在redux状态,然后 将它们连接到您的组件

  • 此软件包由两部分组成:一部分允许您延迟 容器渲染,直到发生某些异步操作。另一个 将数据存储到redux状态,并将加载的数据连接到 容器

在承诺兑现之前,您的组件不会呈现

主要优势是:

import { createStore, applyMiddleware } from 'redux';
import promise from 'redux-promise'; 

const store = configureStore();
store.dispatch(loadBlogs());
...
...
store.dispatch(getWeatherReports());

const storeWithMiddleWare = applyMiddleware(promise)(store);
  • 简单而优雅地配置CSR(客户端渲染)和SSR(服务器端渲染)

  • 您可以在自己的还原程序中对数据加载或加载成功等获取操作做出反应

  • 您可以创建自己的中间件来处理Redux异步连接操作
  • 只需使用简单的redux
    @connect
  • 最后,您可以使用Redux开发工具调试和查看数据

  • 它还与集成,以防止在加载数据之前进行路由转换

确保不要忘记配置()的4个步骤:

import { createStore, applyMiddleware } from 'redux';
import promise from 'redux-promise'; 

const store = configureStore();
store.dispatch(loadBlogs());
...
...
store.dispatch(getWeatherReports());

const storeWithMiddleWare = applyMiddleware(promise)(store);
  • 连接数据,类似于react redux@Connect
  • 作为道具访问数据
  • 连接redux异步减速器
  • 使用ReduxAsyncConnect中间件渲染路由器

  • 因此,在
    仪表板页面
    假设
    getWeatherReports()
    将返回一个承诺),我们可以做的是:

    如果您有使用装饰器的babel预设:

    import { asyncConnect } from 'redux-connect';
    
    @asyncConnect([{
      key: 'lunch',
      promise: ({ store: { dispatch }, params }) => dispatch(getWeatherReports())
    }])
    export default class DashboardPage extends React.Component {
     ...
    }
    
    否则:

    class DashboardPage extends React.Component {
     ...
    }
    
    
    // sorry for the long name ;)
    const asyncConnectedDashboardPage = asyncConnect([{
      key: 'lunch',
      promise: store.dispatch(getWeatherReports())
    }])
    
    export default asyncConnectedDashboardPage;
    
    使用多重承诺

    @asyncConnect([{
      promise: ({ store: { dispatch, getState } }) => {
        const promises = [];
        const state = getState();
        if (/* some condition */) {
          promises.push(dispatch(loadBlogs()))
        }
    
        if (/* some other condition */) {
          promises.push(dispatch(loadUsers()))
        }
    
        promises.push(dispatch(getWeatherReports()))
        return Promise.all(promises);
      },
    }])
    

    有没有办法使用react-redux的
    connect
    方法来实现这一点?我不可能是唯一一个处理这件事的人,这让我觉得我只是把事情搞错了。事实上,我必须使用其他依赖项,即。。