2017-06-27 62 views
0

我正在创建一个站点来显示一些电话并设置了一个API以从我的数据库中传回最新的电话。在componentWillMount中的我的组件中,我调度一个动作,然后获取API结果并填充我的商店。然后该组件呈现商店中的内容。Redux将初始状态设置为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

是的,我在我的网站上的其他地方做了这些,我有API请求,但我希望有一些方法可以在这种情况下通过正确的初始状态,在这种情况下不需要用户交互,以便Google也能够为搜索引擎优化目的抓取内容 – Phil

回答

1

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

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

+0

你有任何好的教程或服务器端渲染的例子,你推荐?我觉得这对我来说可能更有用,因为我希望获得内容加载的SEO优势。 – Phil