反应-将链接重定向到项目,但不刷新组件

时间:2018-11-29 20:43:22

标签: reactjs react-redux react-router

当我单击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);

完整项目:Link

1 个答案:

答案 0 :(得分:1)

如果您不想在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:

如果您想始终查看StageListStage组件,则需要修复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>
    }
}