【问题标题】:Props bugs with React Router使用 React Router 解决问题
【发布时间】:2018-07-09 10:41:47
【问题描述】:

我正在学习使用 Redux、React 和 React Router。 我遇到过这样的问题:

当我使用 Link 从“/”重定向到“/details/{id}”之类的 URL 时 - 我看到调用了错误的操作创建者。来自“/”组件的动作创建者被称为独立于“/details/{id}”中的组件之一。

但是如果我刷新我的页面,一切都会好起来的。调用正确的操作。

带链接的路由:<Link to={/details/${this.props.movi​​e.id}}>

其他错误:如果我从这个页面按“返回”返回到“/”,我会得到一个错误,我的道具数据未定义。 比如,props 是空的,并且没有从 componentDidMount() 调用 http-request 的 action creator (?)。

但是如果我再次刷新我的页面,一切都会再次好起来的。

路由有什么问题??还是redux?

ReactDOM.render(
    <Provider store={store}>
      <BrowserRouter>
        <Routes />
      </BrowserRouter>
    </Provider>, 
    document.getElementById('root'));


const Routes = () => {
    return <div>
        <Route exact path="/" component={Main} />
        <Route path="/details/:id" component={MovieDetailsContainer} />
    </div>;
}

“/”:

    class MoviesDiscover extends Component {
    componentDidMount() {
        this.props.dicoverMovies();
    }

    render() {
      ...
    }
}

const mapStateToProps = (state) => {
    return {
        items: state.movieItems,
        hasErrored: state.movieHasErrored,
        isLoading: state.movieIsLoading,
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        dicoverMovies: (url) => dispatch(dicoverMovies(url))
    };
};

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

“详细信息/{id}”:

class MovieDetailsContainer extends Component {
    componentDidMount() {
        var id = this.props.match.params.id;
        this.props.getMovie(id); // called from MoviesDiscover instead of this, after routing
    }

    render() {
        var id = this.props.match.params.id;
        ...
    }
}

const mapStateToProps = (state) => {
    return {
        item: state.movieItems,
        hasErrored: state.movieHasErrored,
        isLoading: state.movieIsLoading,
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        getMovie: (url) => dispatch(getMovieDetails(url))
    };
};


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

操作(两个请求相同 - 结果、错误和加载的操作):

 ...
export function moviesDataSuccess(items) {
    return {
        type: MOVIES_RESULTS,
        isLoading: false,
        items: items
    };
}

       export function dicoverMovies() {
        return (dispatch) => {
            dispatch(moviesIsLoading(true));

            API.get(URL_MOVIE_DISCOVER)
              .then(response => {
                dispatch(moviesIsLoading(false));
                dispatch(moviesDataSuccess(response.data));
              })
              .catch(e => {
                console.log(e);
                dispatch(moviesHasErrored(true))
              });
        };
    }

    export function getMovieDetails(id) {
        return (dispatch) => {
            dispatch(moviesIsLoading(true));

            API.get(URL_MOVIE_DETAILS(id))
              .then(response => {
                dispatch(moviesIsLoading(false));
                dispatch(moviesDataSuccess(response.data));
              })
              .catch(e => {
                console.log(e);
                dispatch(moviesHasErrored(true))
              });
        };
    }

减速器:

   export function movieHasErrored(state = false, action) {
    switch (action.type) {
        case MOVIES_ERROR:
            return action.hasErrored;
        default:
            return state;
    }
}

export function movieIsLoading(state = false, action) {
    switch (action.type) {
        case MOVIES_LOADING:
            return action.isLoading;
        default:
            return state;
    }
}

export function movieItems(state = {}, action) {
    switch (action.type) {
        case MOVIES_RESULTS:
            return action.items;
        default:
            return state;
    }
}

const rootReducer = combineReducers({
    movieHasErrored, 
    movieIsLoading, 
    movieItems
});

我很乐意接受所有建议。谢谢。

【问题讨论】:

    标签: javascript reactjs redux react-router react-redux


    【解决方案1】:

    React 路由器首先匹配关闭 URL,我认为问题在于组件的顺序。 我建议您像这样订购它们,它应该会得到解决:

    const Routes = () => {
        return <div>
            <Route path="/details/:id" component={MovieDetailsContainer} />
            <Route exact path="/" component={Main} />
        </div>;
    }
    

    React Router 也有一个用于在 URL 之间切换的组件,如果你的 URL 不明确,你可以利用它:

     import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
     ...
     <Switch>
            <Route path="/about" component={About} />
            <Route path="/company" component={Company} />
            <Route path="/:user" component={User} />
     </Switch>
    

    PS:抱歉,如果这不是您要寻找的答案,我只是想发表评论而不是发布此答案,我还没有直接发表评论的声誉:|

    【讨论】:

      【解决方案2】:

      我的错误在其他地方。

      问题是,我对列表结果和详细信息结果使用相同的操作类型。

      当我打开页面查看详细结果时,我从上一页获得了带有列表结果的道具(因为它们使用相同的动作类型)。在我的详细信息组件获取新数据之前。

      而我的代码在渲染错误数据时失败。

      【讨论】:

        猜你喜欢
        • 2022-06-28
        • 1970-01-01
        • 2017-05-29
        • 2016-01-22
        • 2019-07-07
        • 2020-06-10
        • 2021-07-18
        • 2019-05-30
        • 2021-11-13
        相关资源
        最近更新 更多