在 React 组件中设置初始状态以进行渐进式增强和 Flux 架构

Posted

技术标签:

【中文标题】在 React 组件中设置初始状态以进行渐进式增强和 Flux 架构【英文标题】:Setting the initial state in React components for progressive enhancement & Flux architecture 【发布时间】:2015-02-16 01:51:46 【问题描述】:

我读过http://scotch.io/tutorials/javascript/build-a-real-time-twitter-stream-with-node-and-react-js,它描述了一种无缝接管服务器渲染的 React 组件的技术:

服务器渲染到车把中的 markup,并传递初始状态。

<section id="react-app"> markup </div>
<script id="initial-state" type="application/json">state</script>

然后在客户端javascript

/** @jsx React.DOM */

var React = require('react');
var TweetsApp = require('./components/TweetsApp.react');

// Snag the initial state that was passed from the server side
var initialState = JSON.parse(document.getElementById('initial-state').innerhtml)

// Render the components, picking up where react left off on the server
React.renderComponent(
  <TweetsApp tweets=initialState/>,
  document.getElementById('react-app')
);

但在 Flux 架构中,例如本文http://scotch.io/tutorials/javascript/creating-a-simple-shopping-cart-with-react-js-and-flux 中所述,状态在 getInitialState 生命周期方法中初始化:

// Method to retrieve state from Stores
function getCartState() 
  return 
    product: ProductStore.getProduct(),
    selectedProduct: ProductStore.getSelected(),
    cartItems: CartStore.getCartItems(),
    cartCount: CartStore.getCartCount(),
    cartTotal: CartStore.getCartTotal(),
    cartVisible: CartStore.getCartVisible()
  ;


// Define main Controller View
var FluxCartApp = React.createClass(

  // Get initial state from stores
  getInitialState: function() 
    return getCartState();
  ,

  // Add change listeners to stores
  componentDidMount: function() 
    ProductStore.addChangeListener(this._onChange);
    CartStore.addChangeListener(this._onChange);
  ,

  // Remove change listers from stores
  componentWillUnmount: function() 
    ProductStore.removeChangeListener(this._onChange);
    CartStore.removeChangeListener(this._onChange);
  ,

  // Render our child components, passing state via props
  render: function() 
    return (
      <div className="flux-cart-app">
        <FluxCart products=this.state.cartItems count=this.state.cartCount total=this.state.cartTotal visible=this.state.cartVisible />
        <FluxProduct product=this.state.product cartitems=this.state.cartItems selected=this.state.selectedProduct />
      </div>
    );
  ,

  // Method to setState based upon Store changes
  _onChange: function() 
    this.setState(getCartState());
  

);

module.exports = FluxCartApp;

从渐进增强的角度来看,哪一种是设置状态的正确方法?

【问题讨论】:

【参考方案1】:

考虑到渐进增强,我喜欢通量和反应如何协同工作。

我在我当前的项目中使用 ReactJS 和 Flux,一切都很干净和简单。您所需要注意的只是在真正需要时展示一些创建新商店的纪律。不过,我不太喜欢 eventEmitter 的东西。我只是触发了我在单独的 eventConstants.js 文件中定义的自己的事件,这使我可以让多个组件在同一个商店中监听不同的更改。

这确实可以很好地扩展。

回答你的问题:

这确实取决于您的用例。忽略在服务器上呈现初始页面对 SEO 来说非常有用,它只有在用户都应该看到几乎相同的内容时才有意义在服务器上呈现。我喜欢把客户的东西放在客户身上。

希望对你有帮助

【讨论】:

离题,但您为什么要关心商店的具体变化?我最喜欢 react/flux 的一点是我不必关心具体发生了什么变化。 也许这只是适合我的项目,但我与后端和 websockets 一起工作。我时不时地在 websocket 客户端收到一些东西。我有几个已安装的组件与此商店相关联,但不需要了解有关此特定发射的任何信息。 为什么你有一个组件监听一个没有从它获取任何数据的存储?

以上是关于在 React 组件中设置初始状态以进行渐进式增强和 Flux 架构的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的状态没有在这个组件中设置

如何在打字稿中设置初始 React 状态?

有没有办法在 useEffect 的反应组件中设置 xstate 机器的状态?

在样式化组件中设置 React 组件道具

你如何在反应中设置一个组件与不同组件的状态?

ReactJS 在功能组件中设置状态的基本问题