2016-04-08 1 views
0

Я только начал интегрировать интерактивный маршрутизатор в свое приложение, и он работает как шарм. Однако у меня есть одна небольшая проблема. В какой-то момент мне нужно щелкнуть по кнопке, которая изменяется на другую страницу, но также необходимо выполнить вызов (который идет на сервер и получает данные, которые будут показаны в таблице). В настоящий момент ссылка-ретранслятор запускается перед действием и поэтому разбивает приложение в этот момент, так как нет данных для отображения!React-router - слишком скоро срабатывает Link

Вопрос в том, как я могу изменить порядок, в котором происходят эти события, чтобы в момент хранения страницы присутствовали данные в хранилище (обновляется действием)?

Текущий код блока:

import React from 'react'; 
import { Link } from 'react-router'; 
import List from 'material-ui/lib/lists/list'; 
import ListItem from 'material-ui/lib/lists/list-item'; 
import ActionInfo from 'material-ui/lib/svg-icons/action/info'; 
import { getTable } from '../../actions/DALIActions'; 
import TokenStore from '../../stores/TokenStore'; 
import TableStore from '../../stores/TableStore'; 

const styles = { 
    root: { 
     paddingTop: 200, 
     width: '100%', 
    }, 
    headerStyle: { 
     textAlign: 'center', 
    }, 
    container: { 
     border: 'solid 1px #d9d9d9', 
     height: 500, 
     overflow: 'hidden', 
    }, 
}; 

class MainTablePage extends React.Component { 

    getTable(id) { 
     getTable(TokenStore.getToken(), id); 
    } 

    addTables() { 
     let tableArray = TableStore.getTables().objects; 
     console.log(tableArray); 
     let tableList = tableArray.map((el, i) => { 
      return (
       <ListItem 
        key={i} 
        id={el.id} 
        primaryText={el.title} 
        leftIcon={<ActionInfo />} 
        containerElement={<Link to="/table" />} 
        linkButton={true} 
        onTouchTap={this.getTable.bind(this, el.id)} 
       /> 
      ); 
     }); 
     return tableList; 
    } 

    render() { 
     return (
      <div> 
       <div style={styles.headerStyle}> 
        <h1>Here are the current tables available</h1> 
       </div> 
       <div style={styles.root}> 
        <div style={styles.container}> 
         <List> 
          {this.addTables()} 
         </List> 
        </div> 
       </div> 
      </div> 
     ); 
    } 
} 

export default MainTablePage; 

Ах да, я использую материал-интерфейс, так что, вероятно, не поможет вопросов!

Любая помощь будет высоко ценится

Спасибо за ваше время

+0

Попробуйте ввести API-вызов в 'componentDidMount', а затем' setState', когда данные будут возвращены, тем самым повторно визуализируя представление. См. Здесь: https://facebook.github.io/react/tips/initial-ajax.html – lux

+0

Вы предпочли бы, чтобы пользователь подождал после нажатия кнопки ИЛИ, если бы вы изменили страницу и дождались завершения API и покажите загрузчик тем временем. Поскольку вызов API займет некоторое время, и если вы не измените страницу, пользователь снова и снова нажимает кнопку. –

ответ

2

Пожарной действие в компонентах componentDidMount() и установить состояние загрузки в вашем магазине.

Когда действие активировано и выполняется запрос, заданное состояние загрузки равно true. Как только данные будут получены, установите значение false. Таким образом вы выполняете загрузку вместо компонентов, которые полагаются на данные, которые не были извлечены.

Я обновил ваш код, чтобы показать, как он будет работать. Позвольте мне знать, если у вас есть еще вопросы.

Ссылка на React's lifecycle methods для получения дополнительной информации.

class MainTablePage extends React.Component { 
    componentDidMount() { 
     // fire your action here 
    } 
    getTable(id) { 
     getTable(TokenStore.getToken(), id); 
    } 

    addTables() { 
     let tableArray = TableStore.getTables().objects; 
     console.log(tableArray); 
     let tableList = tableArray.map((el, i) => { 
      return (
       <ListItem 
        key={i} 
        id={el.id} 
        primaryText={el.title} 
        leftIcon={<ActionInfo />} 
        containerElement={<Link to="/table" />} 
        linkButton={true} 
        onTouchTap={this.getTable.bind(this, el.id)} 
       /> 
      ); 
     }); 
     return tableList; 
    } 

    render() { 
     const { loading } = this.props; // loading state from your store 

     if (loading) { 
      // return a loader component while your data is fetched 
      return <Loader />;  
     } 

     return (
      <div> 
       <div style={styles.headerStyle}> 
        <h1>Here are the current tables available</h1> 
       </div> 
       <div style={styles.root}> 
        <div style={styles.container}> 
         <List> 
          {this.addTables()} 
         </List> 
        </div> 
       </div> 
      </div> 
     ); 
    } 
} 
+0

Спасибо за помощь! – BeeNag

+0

Извините, но я действительно не успел правильно ответить. Хотя это похоже на то, что я пытаюсь достичь, действие вызывается так, что данные будут доступны на следующей странице, а не на той странице, в которой я сейчас. По логике, которую вы представили, я предполагаю, что я должен вызывать действие в этом компоненте, но поскольку для этого требуется аргумент id (как видно из функции getTable, где я вызываю действие в данный момент), могу ли я сделать это с componentDidMount? У меня создалось впечатление, что никаких аргументов не было! – BeeNag

+0

Поразмыслив! Еще раз спасибо за точку в правильном направлении! – BeeNag