如何触发与再次渲染无关的组件?

时间:2021-06-28 04:40:38

标签: reactjs

我有一个 Header 组件,它将在导航栏中显示下拉登录、注册和注销。这将被视为组件 A。

而且我还有 Sign In 组件,在我的想法中被认为是组件 B。它将在内容正文中显示一个“登录方式”框和一个“登录”按钮。

我想达到什么目标?如果我登录 -> 我将收到一个令牌,如果在标题处,我有一个令牌,它只会显示注销,如果令牌 = 空,它只会显示登录和注册。

我取得了什么成就?

如果我从标题中按下注销 - 这是下拉导航栏,我可以将令牌的状态设置为 null,因此状态更改,它将再次呈现组件,这将更新并显示Sign-up and Sign-in since token = null 因为我删除了 localStorage

中的令牌

问题是:

这不适用于 Sign-in 组件,因为它来自一个完全不同的组件,它与标题没有任何关系。如果我从 Sign In 组件按下登录按钮,我可以获得令牌并将其推送到 localStorage,但我必须手动刷新网页以便它可以再次呈现,我找不到方法将该令牌传递到标头中,以便它可以作为状态接收以使其再次呈现。

我需要帮助,谢谢。我认为有一种方法,即使用 Redux 或其他东西来存储状态,但我不知道如何使用它,所以请问有什么方法可以仅使用 React 来做到这一点?

Header 组件:

export default function Header(props) {
    const [token, setToken] = useState(localStorage.getItem("token"));
    const onClickToSignOut = () => {
        localStorage.removeItem("token");
        setToken(null);
    };

    useEffect(() => {
        setToken(token);
    }, [token]);

    return (
        <div className="header">
            <div className="logo">
                <img src="./Demo/assets/images/logo.png" alt="SCC Logo" />
            </div>
            <ul id="nav">
                <li>
                    <Link to="/">Home</Link>
                </li>
                <li>
                    <Link to="/contact">Contact</Link>
                </li>
                <li>
                    <Link to="/quiz-topics">Quiz Topic</Link>
                </li>
                <li>
                    <a href="#">
                        <i className="ti-user"></i>
                    </a>
                    <ul className="subnav">
                        {!token ? (
                            <>
                                <li>
                                    <Link to="/sign-in">Sign in </Link>
                                </li>
                                <li>
                                    <Link to="/sign-up">Sign up</Link>
                                </li>
                            </>
                        ) : (
                            <>
                                <li>
                                    <Link to="/sign-in" onClick={onClickToSignOut}>
                                        Log out
                                    </Link>
                                </li>
                            </>
                        )}
                    </ul>
                </li>
            </ul>
            <div id="mobile-menu" className="mobile-menu-btn">
                <i className="menu-icon ti-menu"></i>
            </div>
        </div>
    );
}

SignIn 组件:

class SignIn extends Component {
    constructor(props) {
        super(props);
        this.state = {
            username: "",
            password: "",
        };
    }

    handleOnChange = (event) => {
        let { name, value } = event.target;

        this.setState({
            [name]: value,
        });
    };

    handleOnSubmit = (event) => {
        event.preventDefault();
        let { username, password } = this.state;
        if (username === "" && password === "") {
            toast.warning(`Please enter all the fields`);
        } else if (username === "") {
            toast.error(`Please enter your username`);
        } else if (password === "") {
            toast.error(`Please enter your password`);
        } else {
            callApi("sign-in", "POST", {
                username: username,
                password: password,
            }).then((res) => {
                if (res.data.token) {
                    localStorage.setItem("token", res.data.token);
                    this.setState({ token: res.data.token });
// I want to do something in here that can trigger the Header component after I receive the token when I'm pressing submit at the login//
                    toast.success(`Successfully log in.`);
                    this.props.history.push("/");
                } else {
                    toast.error(`There is something wrong, please try again.`);
                }
            });
        }
    };
    render() {
        return (
            <div className="register-page height-fixed">
                <div id="toast"></div>
                <div
                    style={{
                        background:
                            "url('/Demo/assets/images/slider/slider1.jpg'), no-repeat, fixed, center",
                        height: "100vh",
                    }}
                >
                    <div className="register-section vertical-center">
                        <h2>Sign in</h2>
                        <div className="user-info">
                            <form onSubmit={this.handleOnSubmit}>
                                <div className="row">
                                    <div className="username-line">
                                        <div className="col-25">
                                            <label htmlFor="username">Username</label>
                                        </div>
                                        <div className="col-75">
                                            <input
                                                onChange={this.handleOnChange}
                                                type="text"
                                                placeholder="Enter username"
                                                name="username"
                                                value={this.state.username}
                                            />
                                        </div>
                                    </div>
                                </div>
                                <div className="row">
                                    <div className="password-line">
                                        <div className="col-25">
                                            <label htmlFor="password">Password</label>
                                        </div>
                                        <div className="col-75">
                                            <input
                                                onChange={this.handleOnChange}
                                                type="password"
                                                placeholder="Enter password"
                                                name="password"
                                                value={this.state.password}
                                            />
                                        </div>
                                    </div>
                                </div>

                                <div className="user-info-button">
                                    <Link to="/sign-up">
                                        <button className="btn btn--success btn--danger">
                                            Sign up
                                        </button>
                                    </Link>

                                    <button type="submit">Log in</button>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        );
    }
}
export default SignIn;

0 个答案:

没有答案