Redux将初始状态设置为API响应

时间:2017-06-27 23:13:08

标签: javascript reactjs redux store

我正在创建一个网站来显示一些手机,并设置了一个API来从我的数据库中传回最新的手机。在componentWillMount中的我的组件中,我将调度一个操作,然后获取API结果并填充我的商店。然后该组件呈现商店中的内容。

这似乎一切正常,但确实意味着有一些时间在进行API调用时没有显示任何内容。

我想知道是否有某种方法可以在服务器上调度操作并将initialState设置为API响应,或者将API响应从服务器传递到客户端的其他方式,以便数据存在已经在组件呈现时?

这就是我到目前为止......

减速

export function latestPhonesHasErrored(state = false, action) {
    switch (action.type) {
        case 'LATEST_PHONES_HAS_ERRORED':
            return action.latestPhonesHasErrored;
        default:
            return state;
    }
}

export function latestPhonesIsLoading(state = false, action) {
    switch (action.type) {
        case 'LATEST_PHONES_IS_LOADING':
            return action.latestPhonesIsLoading;
        default:
            return state;
    }
}

export function latestPhones(state = [], action) {
    switch (action.type) {
        case 'LATEST_PHONES_FETCH_DATA_SUCCESS':
            return action.latestPhones;
        default:
            return state;
    }
}

动作

export function latestPhonesFetchData() {
    return (dispatch) => {
        dispatch(latestPhonesIsLoading(true));

        fetch('/api/latest-phones/')
            .then((response) => {
                if (!response.ok) {
                    throw Error(response.statusText);
                }

                dispatch(latestPhonesIsLoading(false));

                return response;
            })
            .then((response) => response.json())
            .then((results) => 
dispatch(latestPhonesFetchDataSuccess(results)))
            .catch(() => dispatch(latestPhonesHasErrored(true)))
    }
}

Server.js

const store = createStore(
    rootReducer,
    initialState,
    applyMiddleware(thunk)
);
const router = express.Router();

router.get('/', (req, res) => {
        match({routes, location: req.originalUrl}, (err, redirectLocation, renderProps) => {
            if(!err) {
                const html = this.render(renderProps);

                res.render('index', {
                    content: html,
                    pageTitle: 'title',
                    description: 'description',
                    canonical: 'canonical'
                });
            } else {
                res.status(500).send();
            }
        });
    });

render(renderProps) {
    let html = renderToString(
        <Provider store={store}>
            <RouterContext {...renderProps}/>
        </Provider>
    );
    return html;
}

组件

import {latestPhonesFetchData} from '../../../actions/results-actions';

const mapStateToProps = (state) => {
    return {
        latestPhones: state.latestPhones
    }
};

class Home extends Component {
    componentWillMount(){
        this.props.latestPhonesFetchData(); 
    }

    render(){
        /* all component render here*/
    }
}
export default connect(mapStateToProps, {latestPhonesFetchData})(Home);

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

如果您在客户端(您是)上呈现React,那么在组件呈现之前没有预先加载数据的方法。 @ A.Lau上面的评论是正确的......你最好的选择是在获取数据的同时渲染一个加载微调器或一些等价物。

或者,您可以使用服务器端呈现。这意味着提前呈现React并将HTML文件提供给客户端。通过在服务器上呈现,您可以从数据库中获取所需的数据,并在呈现之前将其作为props传递给组件。不需要AJAX,您永远不必向客户端显示加载视图。