2016-08-06 40 views
0

更新:問題隔離 - React的react-rails和npm版本不同 - 修復自己的答案Rails 5 Redux React服務器端渲染爲客戶端提供了JavaScript警告'用一個新的替換React渲染的子...'

使用在軌道上軌5 - 反應,得到這樣的警告:

Replacing React-rendered children with a new root component. If you 
intended to update the children of this node, you should instead have 
the existing children update their state and render the new 
components instead of calling ReactDOM.render. 

該網站看起來做工精細,但顯然東西了:)

index.html.erb:

<div class="item"> 
    <%= react_component('WeatherRoot', {}, { :prerender => true }) %> 
</div> 

components.js:

window.React = require('react'); 
window.ReactDOM = require('react-dom'); 
window.WeatherRoot = require('./components/containers/WeatherRoot.es6').default; 

WeatherRoot.es6.js

import React, { Component } from 'react'; 
import { render } from 'react-dom' 
import { Provider } from 'react-redux'; 
import WeatherContainer from './WeatherContainer.es6'; 
import configureStore from '../store/configureStore.es6'; 

import {fetchWeather} from '../actions/weather.es6'; 

const store = configureStore(); 

// Request Data as Early as Possible 
store.dispatch(fetchWeather()); 

export default class WeatherRoot extends Component { 
    render() { 
    return (
     <Provider store={store}> 
     <WeatherContainer /> 
     </Provider> 
    ); 
    } 
} 

WeatherContainer.es6

import { connect } from 'react-redux' 
import Weather from '../components/Weather.es6'; 


export function WeatherContainerImpl(props){ 
    return (<div>HELLO</div>); 
} 

const mapStateToProps = (state, ownProps) => { 
    return { 
    weather: state.weather.data 
    } 
} 

const mapDispatchToProps = (dispatch, ownProps) => { 
    return { 
    dispatch 
    } 
} 

const WeatherContainer = connect(
    mapStateToProps, 
    mapDispatchToProps 
)(WeatherContainerImpl); 

export default WeatherContainer; 

頁面呈現:

<div data-react-class="WeatherRoot" data-react-props="{}"> 
    <div data-reactroot="" data-reactid="1" data-react-checksum="-951512882">HELLO</div> 
</div> 

更換爲客戶端繪製:

<div data-react-class="WeatherRoot" data-react-props="{}"> 
    <div data-reactid=".0">HELLO</div> 
</div> 

調試ReactMount.js示出了該方法返回true是所述警告的來源:從

/** 
* True if the supplied DOM node has a direct React-rendered child that is 
* not a React root element. Useful for warning in `render`, 
* `unmountComponentAtNode`, etc. 
* 
* @param {?DOMElement} node The candidate DOM node. 
* @return {boolean} True if the DOM element contains a direct child that was 
* rendered by React but is not a root element. 
* @internal 
*/ 
function hasNonRootReactChild(node) { 
    var reactRootID = getReactRootID(node); 
    return reactRootID ? reactRootID !== ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID) : false; 
} 

基本上節點的「1」的一個id服務器端渲染和

ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID) 

返回NULL這個實現:

(id) { 
    if (id && id.charAt(0) === SEPARATOR && id.length > 1) { 
    var index = id.indexOf(SEPARATOR, 1); 
    return index > -1 ? id.substr(0, index) : id; 
    } 
    return null; 
} 

看起來像id需要以a開頭。通過?

爲什麼服務器端不能以a開頭?

也許我有不同版本的反應?但兩者看起來像14.8

添加一些調試:

export function WeatherContainer(props){ 
    console.log("WeatherContainer", React.version) 
    return (<div>HELLO</div>); 
} 

顯示這些日誌:

WeatherContainer 15.2.1 
WeatherContainer 0.14.8 

!!!!

現在如何弄清我如何得到兩個版本?

+0

我剛纔讀的整個問題,找出你有兩個不同版本的反應?我會首先解決這個問題,我猜測反應軌道是與一個版本一起發貨的,而你正在使用另一個版本。 –

+0

是啊,花了我幾個小時才弄明白,我在添加筆記,因爲我去對不起會更新標題 – stujo

回答

2

OK我發現這個問題

通過添加控制檯日誌,我能夠看到作出反應的服務器版本的有所不同客戶端版本

export function WeatherContainer(props){ 
    console.log("WeatherContainer", React.version) 
    return (<div>HELLO</div>); 
} 

都給:

WeatherContainer 15.2.1 
WeatherContainer 0.14.8 

注:控制檯日誌是因爲在application.rb中

config.react.server_renderer_options = { 
    files: ["react-server.js", "components.js"], # files to load for prerendering 
    replay_console: true,     # if true, console.* will be replayed client-side 
    } 

的replay_console設置的可視客戶端反應護欄-1.8.1捆綁所以在封裝反應15.2.1

。 JSON我強迫DOM反應,與

npm install -S [email protected] 
npm install -S [email protected] 

在Gemfile中我被迫做出反應,導軌1.5.0

反應和0.14.3版本
gem 'react-rails', '1.5' 

現在都是反應0.14.3

,警告消失

+1

感謝隊友 - 這是我的問題,也是:) – Marty

0

嘗試包裹在<div>你這樣的WeatherRoot迴應:

export default class WeatherRoot extends Component { 
    render() { 
    return (
     <Provider store={store}> 
     <div><WeatherContainer /></div> 
     </Provider> 
    ); 
    } 
} 
+0

嗨,傑克! 我做了這個改變,仍然有同樣的問題,謝謝你的想法! 服務器端:

HELLO
客戶端:
HELLO
stujo

相關問題