【问题标题】:Unable to access the history from the props in a component in React?无法从 React 组件中的 props 访问历史记录?
【发布时间】:2020-02-25 14:28:32
【问题描述】:

我有一个名为 (EnterSystem) 的基本组件,我在其上调用 (Login) 和 (Register) 组件。我通过在 Login 组件中使用 {...this.props} 将道具从 Enter System 传递到 Login 和 Register。提交数据并使用数据库验证后,我使用this.props.history.push("/enterprises") 将其重定向到其他一些组件(ListEnterprises)。但我需要 (ListEnterprise) 组件中的此历史记录,以将其进一步重定向到其他一些组件。但是this.props 是未定义的。任何机构都可以帮忙吗?

进入系统

class EnterSystem extends Component {

    constructor(props) {
        super(props);
        this.state = {
            isLogginActive: true
        };
    }

    componentDidMount() {
        //Add .right by default
        this.rightSide.classList.add("right");
    }

    changeState() {
        const { isLogginActive } = this.state;

        if (isLogginActive) {
            this.rightSide.classList.remove("right");
            this.rightSide.classList.add("left");
        } else {
            this.rightSide.classList.remove("left");
            this.rightSide.classList.add("right");
        }
        this.setState(prevState => ({ isLogginActive: !prevState.isLogginActive }));
    }

    render() {
        const { isLogginActive } = this.state;
        const current = isLogginActive ? "Register" : "Login";
        const currentActive = isLogginActive ? "login" : "register";
        return (
            <div>
                <NavigationComponent />
                <div className="Enter">
                    <div className="login">
                        <div className="container" ref={ref => (this.container = ref)} >
                            {isLogginActive && (
                                <Login {...this.props} containerRef={ref => (this.current = ref)} />
                            )}
                            {!isLogginActive && (
                                <Register {...this.props} containerRef={ref => (this.current = ref)} />
                            )}
                        </div>
                        <RightSide current={current} currentActive={currentActive} containerRef={ref => (this.rightSide = ref)} onClick={this.changeState.bind(this)} />
                    </div>
                </div>
                <FooterComponent />
            </div>
        );
    }
}

const RightSide = props => {
    return (
        <div className="right-side" ref={props.containerRef} onClick={props.onClick}>
            <div className="inner-container">
                <div className="text">{props.current}</div>
            </div>
        </div>
    );
};

export default EnterSystem; 

登录

export class Login extends Component {

    emptyCredential = {
        username: "",
        password: "",
    }

    constructor(props) {
        super(props);

        this.state = {
            isLoading: false,
            hasLoginFailed: false,
            showSuccessMessage: false,
            credential: this.emptyCredential
        }

        this.handleChange = this.handleChange.bind(this);
        this.loginClicked = this.loginClicked.bind(this);
    }


    handleChange(event) {
        const target = event.target;

        const value = target.value;
        const name = target.name;

        let updatedCredential = { ...this.state.credential };
        updatedCredential[name] = value;
        this.setState({ credential: updatedCredential });
        console.log(updatedCredential);
    }

    loginClicked(event) {
        const payload = this.state.credential;
        console.log("Printing Payload ");
        console.log(payload);
        console.log(payload.username);
        console.log(payload.password)
        AuthenticationService.executeJwtAuthenticationService(payload)
            .then(response => {
                console.log(response.data);
                AuthenticationService.registerSuccessfulLoginForJwt(payload.username, response.data.id_token);
                this.setState({ isLoading: false, hasLoginFailed: false, showSuccessMessage: true });
                this.props.history.push("/enterprises");
                // // <Redirect to={{
                // //     pathname: '/enterprises'
                // // }}
                // // />
                // <ListEnterprises name="history" historyId="this.props"  />
                // this.props.history.push({ pathname: "/enterprises" });
            })
            .catch(error => {
                console.log(error);
                this.setState({ isLoading: false, hasLoginFailed: true, showSuccessMessage: false });
            });
    }

    render() {
        return (
            <div className="base-container" ref={this.props.containerRef}>
                <div className="header">Login</div>
                <div className="content">
                    <div className="image">
                        <img src={LoginImg} />
                    </div>
                    {this.state.hasLoginFailed && <div className="alert alert-warning">Invalid Credentials</div>}
                    {this.state.showSuccessMessage && <div>Login Sucessful</div>}
                    <div className="form">
                        <div className="form-group">
                            <label htmlFor="username" for="username">Username</label>
                            <input type="text" name="username" id="username" placeholder="username" onChange={this.handleChange} />
                        </div>
                        <div className="form-group">
                            <label htmlFor="password" for="password">Password</label>
                            <input type="password" name="password" id="password" placeholder="password" onChange={this.handleChange} />
                        </div>
                    </div>
                </div>
                <div className="footer">
                    <button type="button" className="btn" onClick={this.loginClicked}>Login</button>
                </div>
            </div>
        );
    }
}

企业列表

class ListEnterprises extends Component {


    constructor(props) {
        super(props);
        this.state = {
            isLoading: true,
            enterprises: [],
            message: null,
            showFormMessage: false,
        }
        //Any method in a react component should be bound to this
        this.refreshEnterprises = this.refreshEnterprises.bind(this);
    }

    // After all the elements of the page is rendered correctly, this method is called.
    // After the markup is set on the page, this technique called by React itself to either fetch the data from An External API or perform some unique operations which need the JSX.API
    // componentDidMount() method is the perfect place, where we can call the setState() method to change the state of our application and render() the updated data loaded JSX. For example, we are going to fetch any data from an API then API call should be placed in this lifecycle method,
    // and then we get the response, we can call the setState() method and render the element with updated data.
    //React defines a component lifecycle. componentDidMount will be called as soon as the component is mounted. We are calling refreshCourses as soon as a component is mounted.
    componentDidMount() {
        this.refreshEnterprises();
    }

    _showMessage = (bool) => {
        this.setState({
            showFormMessage: bool
        });
    }

    refreshEnterprises() {
        EnterpriseService.retrieveAllEnterprises()
            .then((response) => {
                console.log(response.data);
                this.setState({ enterprises: response.data, isLoading: false });
            }).catch((error) => {
                console.log(error);
            });
    }

    render() {
        console.log("Rendering Enterprises");

        if (this.state.isLoading)
            return (<div>Loading...</div>);

        return (
            <div>
                <NavigationComponent /><br /><br />
                <h3 align="center">Here are all your Enterprises</h3><br />
                {this.state.message && <div class="alert alert-success">{this.state.message}</div>}
                <Container>
                    <Table striped bordered hover size="sm">
                        <thead>
                            <tr>
                                <th>Enterprise</th>
                                <th>Industry</th>
                                <th>Description</th>
                                <th>Update</th>
                                <th>Delete</th>
                            </tr>
                        </thead>
                        <tbody>
                            {
                                this.state.enterprises.map(
                                    enterprise =>
                                        <tr key={enterprise.id}>
                                            <td>{enterprise.enterpriseName}</td>
                                            <td>{enterprise.industry}</td>
                                            <td>{enterprise.description}</td>
                                            <td><button className="btn btn-success">Update</button></td>
                                            <td><button className="btn btn-warning">Delete</button></td>
                                        </tr>
                                )
                            }
                        </tbody>
                    </Table>
                </Container>{" "}{" "}{" "}

                <div className="container">
                    <Button color="primary" size="lg" onClick={this._showMessage.bind(null, true)}>Add Enterprise</Button>{' '}
                    <Button color="secondary" size="lg" onClick={this._showMessage.bind(null, false)}>Hide</Button>{' '}
                    {this.state.showFormMessage && (<AddEnterprise {...this.props} />)}
                </div>
                <FooterComponent />
            </div >
        );
    }
}

export default ListEnterprises;

App.js(路由在这里定义)

class App extends Component {
  state = {}
  render() {
    return (
      <Router>
        <Switch>
          <Route path="/" exact={true} component={Home} />
          <Route path="/enter" exact={true} component={EnterSystem} />
          <Route path="/enterprises"><ListEnterprises /></Route>
          // {/* <Route path='/categories' exact={true} component={Category} /> */}
          {/* <Route path='/expenses' exact={true} component={Expenses} /> */}
        </Switch>
      </Router>
    );
  }
}

export default App;

需要从 ListEnterprises 发送 props 到 AddEnterprise。

提前感谢您的帮助。

【问题讨论】:

  • 如果您认为您的问题已经解决,请考虑marking an answer as accepted。 “接受答案很重要,因为它奖励正确回答您问题的海报,通知其他人您的问题已解决,并将答案固定在顶部,以便其他阅读您的问题的人首先阅读该答案。”。有美好的一天????。
  • 非常感谢您的帮助。我接受了答案:-)

标签: reactjs react-router react-props


【解决方案1】:

确保&lt;ListEnterprises /&gt; 被加载为Route componenthistory 将自动在道具中提供并且可以使用this.props.history 访问。

<Route path="/enterprises" component={ListEnterprises} />

【讨论】:

  • 谢谢...它工作正常。现在我可以访问 this.props.history。有效负载正在添加到数据库中,但它没有重定向到“ListEnterprises”。实际上,什么都没有发生。但是,当我刷新 ListEnterprise 组件时,我看到了更新的数据。
  • 很高兴您现在可以访问历史记录。听起来您在处理请求的答案时遇到了一些问题,可能是其他问题的完美问题?。
  • @gibran:你是不是错过了点击并接受了我的回答,应该是 sebastiam 的,对吧?
  • 知道如何从一个组件重定向到同一个组件吗?例如:- 从组件 A 重定向到组件 A(在 DB 操作后更新数据)
【解决方案2】:

withRouter HOC(高阶组件)添加到您的组件中并像下面这样使用它:

import { withRouter } from "react-router";

class ListEnterprises extends Component {/* Your component code goes here */}

export default withRouter(ListEnterprises);

【讨论】:

    猜你喜欢
    • 2019-08-03
    • 2023-03-30
    • 2016-01-07
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 2021-02-24
    • 2021-09-03
    • 1970-01-01
    相关资源
    最近更新 更多