2016-08-08 2 views
0

Я создаю очень простое изоморфное приложение React/Redux и в одном из моих контейнеров хочу загрузить данные пользователя и список их альбомов.Isomorphic React Ошибка повторного использования метки приложения

вроде все работает нормально как сервер и клиентская стороны, но я получаю ошибку:

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server: 
(client) iv data-reactid="2">Loading...</div></di 
(server) iv data-reactid="2"><a href="/users" dat 

Я понимаю, что это происходит потому, что при загрузке сервер и клиент может отличаться, поскольку клиент занимает больше времени для выборки данных. Однако как мне обойти эту проблему?

Если я удалю {!user}, то страница не отобразится, и я получаю сообщение об ошибке, указывающее, что {user.firstName} не существует.

Вот мой код компонента:

// IMPORT DEPENDENCIES 
// ============================================== 

import React, {Component, PropTypes} from 'react'; 
import {Link} from 'react-router'; 
import {connect} from 'react-redux'; 
import {getAlbumsByUserId} from '../../redux/album/albumActions'; 
import {getUser} from '../../redux/user/userActions'; 

// USER CONTAINER 
// ============================================== 

export class User extends Component { 

static propTypes = { 
    getAlbumsByUserId: PropTypes.func, 
    getUser: PropTypes.func, 
    params: PropTypes.object, 
    user: PropTypes.object 
}; 

static needs = [ 
    getAlbumsByUserId, 
    getUser 
]; 

componentWillMount() { 
    this.props.getAlbumsByUserId(); 
    this.props.getUser(); 
} 

render() { 
    const {albums, user} = this.props; 

    if (!user) { 
     return <div>Loading...</div>; 
    } 

    return (
     <div> 
      <Link to='/users'>Back to users</Link> 
      <h1>User: {user.firstName} {user.lastName}</h1> 

      {albums && 
       albums.map((album) => 
        <div key={album.id}> 
         <h2> 
          <Link to={`/albums/${album.id}`}> 
           {album.title} 
          </Link> 
         </h2> 
        </div> 
       ) 
      } 
     </div> 
    ); 
} 
} 





// MAPPINGS 
// ============================================== 

const mapStateToProps = ({albums, users}) => { 
    return { 
     albums: albums.list.items, 
     user: users.activeItem.item 
    }; 
}; 

const mapDispatchToProps = (dispatch, props) => { 
    return { 
     getAlbumsByUserId:() => { dispatch (getAlbumsByUserId(props.params)); }, 
     getUser:() => { dispatch(getUser(props.params)); } 
    }; 
}; 





// EXPORT 
// ============================================== 

export default connect(mapStateToProps, mapDispatchToProps)(User); 

static needs сообщает серверу, какие действия он требует загрузки страницы.

+0

в стороне клиента отображает

Loading...
в стороне сервера отображается

ответ

-1

Обычно, имея дело с изоморфным способом, мы передаем inital data с сервера вместе с индексным файлом, а затем загружаем данные с помощью ajax. , например. в нашем основном HTML-файле у нас будет что-то вроде

<script> 
    var APP_PROPS = JSON.stringify(props); 
</script> 

и используйте эти данные для первоначального рендеринга.

+0

У меня это есть, однако исходное состояние становится устаревшим после начала изменения маршрутов. – Paul

+0

Сериализация исходных данных с помощью JSON.stringify сделает ваше приложение уязвимым для атак XSS. Вместо этого вы должны использовать serialize-javascript (или что-то в этом роде). – koorchik

+0

Согласовано, это для демонстрации и простоты понимания цели. Мы обертываем JSON.stringify для удаления тегов (скриптов и всех) и некоторых специальных символов –

Смежные вопросы