Реагировать - ссылка перенаправить на элемент, но не обновить компонент - PullRequest
0 голосов
/ 29 ноября 2018

Когда я щелкаю StageItem 'Details', URL изменяется, но компонент Stage не обновляет данные.Я пытался использовать Switch и withRouter, но безуспешно, потому что я совершенно не знаю, как использовать их в моем случае.Заранее спасибо за ответы.Мой код:

Приложение

class App extends Component {
  render() {
    return (
        <BrowserRouter>
          <div className="App">
            <Header/>
            <div className="container">
                <div className="row">
                    <Route path='/' component={InputContainer}/>
                    <Route path='/' component={() => <StagesList todos={this.props.todos}/>} />
                    <Route path='/:stage_id' render={(props) => <Stage {...props} todos={this.props.todos}/>} />
                </div>
            </div>
          </div>
        </BrowserRouter>
    );
  }
}

const mapStateToProps = state => {
    return {
        todos: state.todos
    };
};

const mapDispatchToProps = {};

export const AppContainer = connect(mapStateToProps, mapDispatchToProps)(App);

StageItem

export const StageItem = ({ todo, id, handleRemoveTodo}) => {

    return(
        <li className="stage_item" key={id}><span onClick={() => handleRemoveTodo(id)}><FontAwesomeIcon className="fa" icon="trash" />&nbsp;{todo.tour} - {todo.duration.hours}:{String(todo.duration.minutes).padStart(2,"0")}:{String(todo.duration.seconds).padStart(2,"0")} - {todo.distance} km - {todo.avgSpeed} km/h - {todo.maxSpeed} km/h</span><Link to={'/'+todo.id}>Details</Link></li>
    )

};

StagesList

export class StagesListC extends React.Component{

    render(){

        return(
            <div className="col-12 col-sm-12 col-md-12 col-lg-12">
                <SectionTitle title="Stage list"/>
                {this.props.todos.length>0 ?
                <ul className="todo-list">
                    {this.props.todos.map((todo) => <StageItem
                        key={todo.id}
                        id = {todo.id}
                        todo={todo}
                        handleRemoveTodo = {this.props.handleRemoveTodo}
                    />)}
                </ul>
                :
                <div>You have no stages</div>}
            </div>
        )
    }

}

const mapStateToProps = dispatch => bindActionCreators({
    handleRemoveTodo
}, dispatch)

const mapDispatchToProps = { handleRemoveTodo };

export const StagesList = connect(mapStateToProps, mapDispatchToProps)(StagesListC);

Полный проект: Ссылка

1 Ответ

0 голосов
/ 01 декабря 2018

Вам нужно добавить exact к вашим / маршрутам, если вы не хотите видеть InputContainer и StagesList, пока вы находитесь на :stage_id маршруте.

<div className="row">
    <Route path='/' exact component={InputContainer}/>
    <Route path='/' exact component={() => <StagesList todos={this.props.todos}/>} />
    <Route path='/:stage_id' render={(props) => <Stage {...props} todos={this.props.todos}/>} />
</div>

В вашем компоненте Stage также есть ошибка.

todo.id - это целое число, но stage_id - это строка.Чтобы исправить это, вы можете преобразовать оба в строку, например

let stage = todos.filter((todo) => String(todo.id) === String(id));

UPD:

Если вы хотите видеть компоненты StageList и Stage в любое время, вам нужно исправитьStage компонент.Компонент Stage обновляет свое значение state.stage только один раз, когда срабатывает componentDidMount.Все последующие обновления не обновляют значение stage.stage.Вы можете реализовать метод componentWillReceiveProps жизненного цикла и обновлять значение stage.stage при каждом изменении реквизита.В качестве альтернативы вы не используете state.stage и вычисляете значение stage на лету в методе render, например:

class Stage extends React.Component {

    getStage = () => {
        const todos = this.props.todos || [];
        let id = this.props.match.params.stage_id;
        return todos.filter((todo) => String(todo.id) === String(id))[0];
    }

    render() {

        const stage = this.getStage();

        if (!stage) return null;

        return <div className="col-12 col-sm-12 col-md-12 col-lg-12">
            <SectionTitle title="Single stage"/>
            <div>Id: {stage.id}</div>
            <div>Distance: {stage.distance}</div>
            <div>Duration: {stage.duration.hours}:{String(stage.duration.minutes).padStart(2, "0")}:{String(stage.duration.seconds).padStart(2, "0")}</div>
            <div>Average speed: {stage.avgSpeed} km/h</div>
            <div>Max speed: {stage.maxSpeed} km/h</div>
        </div>
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...