Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应路由器:从路由器侦听事件获取参数失败_Javascript_Reactjs_React Router_React Router Redux - Fatal编程技术网

Javascript 反应路由器:从路由器侦听事件获取参数失败

Javascript 反应路由器:从路由器侦听事件获取参数失败,javascript,reactjs,react-router,react-router-redux,Javascript,Reactjs,React Router,React Router Redux,我发现当尝试使用react routerrouter.listen(…)获取路由参数时失败了。通过使用window.location.pathname.split('route/')[1],我可以获得参数。有什么建议吗 我一直在想为什么会这样。到目前为止,我注意到它在第一次路由更改(url更改)时失败——我的意思是,通过使用,我的url从/param/y更改为/param/x;但该参数仅在我再次单击时可用。我想这可能与我的行为或我的组件有关?或者侦听器在react生命周期中的位置 不确定我是否用

我发现当尝试使用
react router
router.listen(…)获取路由参数时失败了。通过使用window.location.pathname.split('route/')[1],我可以获得参数。有什么建议吗

我一直在想为什么会这样。到目前为止,我注意到它在第一次路由更改(url更改)时失败——我的意思是,通过使用,我的url从
/param/y
更改为
/param/x
;但该参数仅在我再次单击时可用。我想这可能与我的行为或我的组件有关?或者侦听器在react生命周期中的位置

不确定我是否用错误的生命周期方法或方法声明eventlistener;正如我一直在想的那样,我正在将路由传递到存储,但我想我正在使用withRouter(组件)来完成这个事件。我想我需要使用redux的路由状态。我想

具有侦听器的组件:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { setActiveQuestion, setQuestionAnswer } from '../actions/index';
import { bindActionCreators } from 'redux';
import { Link } from 'react-router';
import Navbar from '../containers/navbar';

class Question extends Component {
    constructor(props) {
        super(props);
        this.getClassName = this.getClassName.bind(this);
    }
    componentWillMount() {
        this.setEventListeners();
    }

    setEventListeners() {
        this.props.router.listen(() => {
            // using location pathname instead, since props.params fail
            //let question_id = this.props.params.question_id;
            let question_id = window.location.pathname.split('question/')[1]
            this.props.setActiveQuestion(question_id);
        });
    }

    setAnswer(answer_id) {
        let question_id = this.props.question.id;
        this.props.setQuestionAnswer(question_id, answer_id);
    }

    getClassName(answers, item_answer_id) {

        let classes = [];

        // find the answer for the active question
        let answer_index = _.findIndex(answers, (answer) => {
            return answer.question_id === this.props.question.id;
        });

        // if there's no answer yet, skip class placement
        if (answer_index === -1) {
            return;
        }

        let answer = answers[answer_index];

        // Test cases
        const isUserCorrect = () => {
            return answer.answer_id == answer.correct_answer_id && item_answer_id == answer.correct_answer_id
        }

        const isUserAnswer = () => {
            return answer.answer_id === item_answer_id;
        }

        const isCorrectAnswer = () => {
            return item_answer_id == answer.correct_answer_id;
        }

        // Test and set the correct case classname for styling
        if (isUserCorrect()) {
            classes.push('user_correct_answer');
        }

        if (isUserAnswer()) {
            classes.push('user_answer');
        }

        if (isCorrectAnswer()) {
            classes.push('correct_answer');
        }

        return classes.length > 0 ? classes.join(' ') : '';

    }

    answersList() {
        return this.props.question.answers.map((answer) => {
            return <li className={ this.getClassName(this.props.answers, answer.id) } key={ answer.id } onClick={ () => this.setAnswer(answer.id) }>{ answer.text }</li>
        });
    }

    render() {
        return (
            <div>
                <div className='question-container'>
                    <h2>{ this.props.question && this.props.question.question }</h2>
                    <ul>
                    {
                        this.props.question &&
                        this.answersList()
                    }
                    </ul>
                </div>
                <Navbar />
            </div>
        );
    }
}

function mapStateToProps(state, ownProps) {
    return {
        question: state.questions.active,
        answers: state.answers
    }
}

function matchDispatchToProps(dispatch) {
    return bindActionCreators({
        setActiveQuestion: setActiveQuestion,
        setQuestionAnswer: setQuestionAnswer
    }, dispatch);
}

export default connect(mapStateToProps, matchDispatchToProps)(withRouter(Question));
应用程序入口点index.js:

import React from 'react';
import ReactDOM from "react-dom";
import { Router, browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux'
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import routes from './config/routes';
import reducers from './reducers';
import promise from 'redux-promise';

const createStoreWithMiddleware = applyMiddleware(promise)(createStore);
const store = createStoreWithMiddleware(reducers);
const history = syncHistoryWithStore(browserHistory, store);

ReactDOM.render(
    <Provider store={ store }>
        <Router history={ history } routes={ routes } />
    </Provider>,
    document.getElementById('app')
);

我在@trying中找到了我非常感激的改进反馈的解决方案。我假设我需要使用withRouter并在其中包装MyComponent,然后监听路由器位置的变化,但这显然是错误的;原因是我存储了减速器中的路由参数,因此我可以在mapStateToProps期间随时调用。更好的解释方法是查看以下代码:

function mapStateToProps(state, ownProps) {
    return {
        my_parameter_name: ownProps.params.my_parameter_name
    }
}

export default connect(mapStateToProps)(MyComponent);
更改的原始源代码如下所示:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { setActiveQuestion, setQuestionAnswer } from '../actions/index';
import { bindActionCreators } from 'redux';
import { Link } from 'react-router';
import Navbar from '../containers/navbar';

class Question extends Component {
    constructor(props) {
        super(props);
        this.getClassName = this.getClassName.bind(this);
    }

    componentWillMount() {
        this.props.setActiveQuestion(this.props.question_id);
    }

    componentWillReceiveProps(nextProps) {
        if (this.props.question_id != nextProps.question_id) {
            this.props.setActiveQuestion(nextProps.question_id);
        }
    }

    setAnswer(answer_id) {
        let question_id = this.props.question.id;
        this.props.setQuestionAnswer(question_id, answer_id);
    }

    getClassName(answers, item_answer_id) {

        let classes = [];

        // find the answer for the active question
        let answer_index = _.findIndex(answers, (answer) => {
            return answer.question_id === this.props.question.id;
        });

        // if there's no answer yet, skip class placement
        if (answer_index === -1) {
            return;
        }

        let answer = answers[answer_index];

        // Test cases
        const isUserCorrect = () => {
            return answer.answer_id == answer.correct_answer_id && item_answer_id == answer.correct_answer_id
        }

        const isUserAnswer = () => {
            return answer.answer_id === item_answer_id;
        }

        const isCorrectAnswer = () => {
            return item_answer_id == answer.correct_answer_id;
        }

        // Test and set the correct case classname for styling
        if (isUserCorrect()) {
            classes.push('user_correct_answer');
        }

        if (isUserAnswer()) {
            classes.push('user_answer');
        }

        if (isCorrectAnswer()) {
            classes.push('correct_answer');
        }

        return classes.length > 0 ? classes.join(' ') : '';

    }

    answersList() {
        return this.props.question.answers.map((answer) => {
            return <li className={ this.getClassName(this.props.answers, answer.id) } key={ answer.id } onClick={ () => this.setAnswer(answer.id) }>{ answer.text }</li>
        });
    }

    render() {
        return (
            <div>
                <div className='question-container'>
                    <h2>{ this.props.question && this.props.question.question }</h2>
                    <ul>
                    {
                        this.props.question &&
                        this.answersList()
                    }
                    </ul>
                </div>
                <Navbar />
            </div>
        );
    }
}

function mapStateToProps(state, ownProps) {
    return {
        question_id: ownProps.params.question_id,
        question: state.questions.active,
        answers: state.answers
    }
}

function matchDispatchToProps(dispatch) {
    return bindActionCreators({
        setActiveQuestion: setActiveQuestion,
        setQuestionAnswer: setQuestionAnswer
    }, dispatch);
}

export default connect(mapStateToProps, matchDispatchToProps)(Question);
import React,{Component}来自'React';
从'react redux'导入{connect};
从“react router”导入{withRouter};
从“../actions/index”导入{setActiveQuestion,setQuestionAnswer};
从“redux”导入{bindActionCreators};
从“反应路由器”导入{Link};
从“../containers/Navbar”导入Navbar;
类问题扩展组件{
建造师(道具){
超级(道具);
this.getClassName=this.getClassName.bind(this);
}
组件willmount(){
this.props.setActiveQuestion(this.props.question_id);
}
组件将接收道具(下一步){
if(this.props.question\u id!=nextrops.question\u id){
this.props.setActiveQuestion(nextrops.question_id);
}
}
设置应答(应答号){
让question_id=this.props.question.id;
this.props.setQuestionAnswer(问题id,答案id);
}
getClassName(答案、项目\u答案\u id){
让类=[];
//找到活动问题的答案
让答案索引=u.findIndex(答案,(答案)=>{
返回answer.question_id===this.props.question.id;
});
//如果还没有答案,请跳过课堂安排
如果(答案索引==-1){
返回;
}
让答案=答案[答案索引];
//测试用例
常量isUserCorrect=()=>{
返回answer.answer\u id==answer.correct\u answer\u id&&item\u answer\u id==answer.correct\u answer\u id
}
常量isUserAnswer=()=>{
返回answer.answer\u id==item\u answer\u id;
}
const isCorrectAnswer=()=>{
返回项目\u答案\u id==answer.correct\u答案\u id;
}
//测试并设置样式的正确案例类名
if(isUserCorrect()){
push('user\u correct\u answer');
}
if(isUserAnswer()){
class.push('user_answer');
}
如果(isCorrectAnswer()){
class.push('correct_answer');
}
返回classes.length>0?classes.join(“”):“”;
}
回答者名单(){
返回此.props.question.answers.map((答案)=>{
return
  • this.setAnswer(answer.id)}>{answer.text}
  • }); } render(){ 返回( {this.props.question&&this.props.question.question}
      { 这个问题&& 这是答案清单() }
    ); } } 函数mapStateToProps(状态,ownProps){ 返回{ 问题id:ownProps.params.question_id, 问题:state.questions.active, 答案:state.answers } } 功能匹配DispatchToprops(调度){ 返回bindActionCreators({ setActiveQuestion:setActiveQuestion, setQuestionAnswer:setQuestionAnswer },派遣); } 导出默认连接(mapStateToProps、matchDispatchToProps)(问题);
    我在@trying中找到了解决方案,以改进反馈,我非常感谢。我假设我需要使用withRouter并在其中包装MyComponent,然后监听路由器位置的变化,但这显然是错误的;原因是我存储了减速器中的路由参数,因此我可以在mapStateToProps期间随时调用。更好的解释方法是查看以下代码:

    function mapStateToProps(state, ownProps) {
        return {
            my_parameter_name: ownProps.params.my_parameter_name
        }
    }
    
    export default connect(mapStateToProps)(MyComponent);
    
    更改的原始源代码如下所示:

    import React, { Component } from 'react';
    import { connect } from 'react-redux';
    import { withRouter } from 'react-router';
    import { setActiveQuestion, setQuestionAnswer } from '../actions/index';
    import { bindActionCreators } from 'redux';
    import { Link } from 'react-router';
    import Navbar from '../containers/navbar';
    
    class Question extends Component {
        constructor(props) {
            super(props);
            this.getClassName = this.getClassName.bind(this);
        }
    
        componentWillMount() {
            this.props.setActiveQuestion(this.props.question_id);
        }
    
        componentWillReceiveProps(nextProps) {
            if (this.props.question_id != nextProps.question_id) {
                this.props.setActiveQuestion(nextProps.question_id);
            }
        }
    
        setAnswer(answer_id) {
            let question_id = this.props.question.id;
            this.props.setQuestionAnswer(question_id, answer_id);
        }
    
        getClassName(answers, item_answer_id) {
    
            let classes = [];
    
            // find the answer for the active question
            let answer_index = _.findIndex(answers, (answer) => {
                return answer.question_id === this.props.question.id;
            });
    
            // if there's no answer yet, skip class placement
            if (answer_index === -1) {
                return;
            }
    
            let answer = answers[answer_index];
    
            // Test cases
            const isUserCorrect = () => {
                return answer.answer_id == answer.correct_answer_id && item_answer_id == answer.correct_answer_id
            }
    
            const isUserAnswer = () => {
                return answer.answer_id === item_answer_id;
            }
    
            const isCorrectAnswer = () => {
                return item_answer_id == answer.correct_answer_id;
            }
    
            // Test and set the correct case classname for styling
            if (isUserCorrect()) {
                classes.push('user_correct_answer');
            }
    
            if (isUserAnswer()) {
                classes.push('user_answer');
            }
    
            if (isCorrectAnswer()) {
                classes.push('correct_answer');
            }
    
            return classes.length > 0 ? classes.join(' ') : '';
    
        }
    
        answersList() {
            return this.props.question.answers.map((answer) => {
                return <li className={ this.getClassName(this.props.answers, answer.id) } key={ answer.id } onClick={ () => this.setAnswer(answer.id) }>{ answer.text }</li>
            });
        }
    
        render() {
            return (
                <div>
                    <div className='question-container'>
                        <h2>{ this.props.question && this.props.question.question }</h2>
                        <ul>
                        {
                            this.props.question &&
                            this.answersList()
                        }
                        </ul>
                    </div>
                    <Navbar />
                </div>
            );
        }
    }
    
    function mapStateToProps(state, ownProps) {
        return {
            question_id: ownProps.params.question_id,
            question: state.questions.active,
            answers: state.answers
        }
    }
    
    function matchDispatchToProps(dispatch) {
        return bindActionCreators({
            setActiveQuestion: setActiveQuestion,
            setQuestionAnswer: setQuestionAnswer
        }, dispatch);
    }
    
    export default connect(mapStateToProps, matchDispatchToProps)(Question);
    
    import React,{Component}来自'React';
    从'react redux'导入{connect};
    从“react router”导入{withRouter};
    从“../actions/index”导入{setActiveQuestion,setQuestionAnswer};
    从“redux”导入{bindActionCreators};
    从“反应路由器”导入{Link};
    从“../containers/Navbar”导入Navbar;
    类问题扩展组件{
    建造师(道具){
    超级(道具);
    this.getClassName=this.getClassName.bind(this);
    }
    组件willmount(){
    this.props.setActiveQuestion(this.props.question_id);
    }
    组件将接收道具(下一步){
    if(this.props.question\u id!=nextrops.question\u id){
    this.props.setActiveQuestion(nextrops.question_id);
    }
    }
    设置应答(应答号){
    让我们提问_
    
    withRouter(connect(function(state, props) { 
        return { question_id: props.params.question_id }; 
    })(MyComponent)
    
    componentWillMount() {
        this.props.setActiveQuestion(this.props.question_id);
    }
    
    componentWillReceiveProps(nextProps) {
        if (this.props.question_id != nextProps.question_id) {
            this.props.setActiveQuestion(nextProps.question_id);
        }
    }