2016-08-16 49 views
1

一个故事:组件挂载后设置状态?

我有一个服务器呈现,但我的应用程序的某些部分不能在那里完成,因为他们使用文档(反应艺术库在画布上绘图)。 我无法呈现所有内容,因为反应会说从服务器和客户端收到的代码不一样。

所以我的解决方案是渲染我的应用程序在服务器上的一部分,然后渲染这部分在客户端,并在下一帧,呈现一切无法呈现在客户端上。

所以我想在componentDidMount使用setState,引发DOM更新,所以它可以包含不能在服务器上进行渲染渲染客户端部分,但eslint说,这是不好的componentDidMount设置状态。从逻辑上说,我不能说在这种情况下为什么它不好。一般来说它不好,因为它会触发DOM更新,但在我的情况下,这是我真正需要的。

你会在这种情况下建议什么?

编辑1: 固定错字,我的意思是componentDidMountcomponentDidUpdate

编辑2: Here是同一个问题,但他们使用改变状态componentDidMount作为一种解决方法。

+0

看一看[文件](https://facebook.github.io/react/ 'getInitialState'的docs/component-specs.html#getinitialstate)。 –

+0

'getInitialState'用于设置初始值,但我没有问题。我的问题是:“组件安装后如何更改状态?” –

回答

0

尝试设置状态componentWillMountcomponentWillUpdate

请注意componentWillMount,它也可以称为服务器端。

+0

我无法在'componentWillMount'中设置状态,因为它会将不同的数据呈现给我从服务器获得的数据。 –

+0

我不能在'componentWillUpdate'做到这一点,它不是在第一渲染调用,它是不是在这种情况下被调用。我的问题不是“在哪里设置状态”,问题是:“组件安装后如何更改状态?”或上面描述的问题的任何其他选择。 –

0

我从你的问题中了解到,组装完成后,服务器和客户端上的数据会发生变化,并且希望组件与更改数据保持同步。 我建议你看一下反应的通量或还原结构。例如,flux是以一种方式实现的,即当组件中的任何内容发生更改时,它会触发操作并监听存储。当存储中的任何内容改变时,组件将重新呈现它自己。

+0

我已经使用了redux,但这是一个不同的问题。我的数据没有改变,我会在服务器上渲染所有东西,我没有任何痛苦,因为我不使用无法在服务器上使用的库(在我的情况下为react-art)。再次,我想知道如何在安装应用程序后触发组件更新。这是我需要的事件,但我在componentDidMount中设置状态不允许在airbnb eslint中使用。 –

0

我想知道如何在安装应用程序后触发组件更新。

在React中,将状态“推”到组件上的传统方法是使用props而不是state。如果您的应用程序需要获取客户端信息并相应地调整组件state,则应执行componentWillReceiveProps。 。

如果你觉得在服务器上渲染和浏览器的状态是一样的那种,并且不希望跟踪的麻烦,其性质属于this.state v this.props,我建议类似如下:

componentWillReceiveProps(nextProps) { 
    this.setState(Object.assign({}, this.state, nextProps)); 
} 

这会将传递的属性合并到组件状态,以便可以使用this.state访问它们。

+0

我的问题不在于改变状态,我的状态一切都很好,不应该改变。问题是我的客户端代码与服务器端代码不同。从服务器发送html后,我有一个空容器,在客户端,我有一个数据在那里。我无法在服务器上渲染这些东西。所以我有警告:“React试图在容器中重用标记,但校验和无效。”所以我想从服务器呈现html,然后添加客户端部分。这就是为什么我需要一个回调,甚至可以在我的状态下更改某些属性并呈现客户端部分的处理程序。 –

+0

如果我可以在没有任何黑客的情况下渲染一次,这将是完美的,但我会收到警告。 –

+0

@RossKhanas我的回答并没有描述黑客攻击,而是“改变我的州的一些财产”的正常方式。看来你的描述这个问题的任何尝试都没有澄清它。考虑在你的问题中添加一些代码示例,并解释为什么简单地将客户端数据作为道具传递并不能解决问题。 –

0

请参阅this链接关于ReactJS - Component Life Cycle。 您应该使用componentWillMount周期。在渲染之前,服务器端和客户端都会执行componentWillMount

+0

我不能那样做,因为我无法在服务器上渲染我的应用程序的一部分,'react-art'具有中断服务器渲染的窗口依赖项。 –

+0

但我可以稍后检查一个相关的技巧。也许它会有所帮助。 –

+0

它可以用于第一次呈现,但不能,因为当页面呈现时,其html与从服务器发送的HTML不同。所以我有一个警告。这就是为什么我想要进行这种回调,以便在下一帧中呈现客户端部分。 –

1

我刚刚编写了一个类似的情况,并愉快地使用componentDidMount禁用ESLint的警告。恕我直言,它是完全有效的,只有在通用的渲染场景。

为什么:在componentDidMount使用discouraged的setState因为你会触发额外的,不必要的渲染。

但是,在您想要区分服务器和客户端行为的通用场景中,您需要额外的渲染,并且为了防止'无法重用标记'错误,您需要在反应与服务器呈现的DOM。简而言之:无论如何你都会渲染两次。

但是,我不建议在叶/哑组件中编写此行为,因为这样做需要假定愚蠢的组件具有其环境(客户端/服务器)的一些知识并呈现设计问题。创建一个可以设置愚蠢组件的道具的组件将是显而易见的解决方案。的setStatecomponentDidMount

0

防止使用。

更新状态后一个部件安装将触发第二render()呼叫,并可能导致财产/布局抖动。 下面的模式被认为是警告:

class MyComponent extends React.Component { 
    componentDidMount(){ 
     this.setState({ 
      data: data 
     }); 
    } 
} 

以下模式不被视为警告:

class MyComponent extends React.Component { 
    constructor(){ 
     this.setState({ 
      data: data 
     }); 
    } 

    componentDidMount(){ 
     ... 
    } 
}