Когда я нажимаю на StageItem «Подробности», 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" /> {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);
Полный проект: Ссылка на сайт





Вам необходимо добавить 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>
}
}
Спасибо за ответ. Я обнаружил эту ошибку '===' ранее. С «точным» работает как положено. Но самый важный вопрос для меня был - можно ли сохранить «StagesList» и показать «Stage» и переключить «Stage», щелкнув «StagesList»?
@scartout Да, это возможно. Проблема в том, что вы обновляете компонент Stage только один раз при запуске componentDidMount. Самым простым решением было бы перенести логику фильтрации в метод render. См. Обновленный ответ.
Прекрасно работает! Благодарю за ваш ответ.
Кто-нибудь поможет ???