Обработка контекста React в приложении. js Component - error Хуки могут вызываться только внутри тела функции - PullRequest
0 голосов
/ 06 мая 2020
below is the App.js file and Error = 'Hooks can only be called inside the body of a function component' comes.
can you please anyone let me know what is the problem and give me the solution.
below is the App.js file and Error = 'Hooks can only be called inside the body of a function component' comes.
can you please anyone let me know what is the problem and give me the solution.
import React, { useState, useContext, createContext } from 'react'
import { BrowserRouter, Route, Switch, NavLink } from "react-router-dom";
import './App.css';
import { routes } from '../src/routes';
import SystemService, { } from './shared/system_service';

export const AuthContext = React.createContext();
const initialState = {
    isAuthenticated: false,
    user: null,
    token: null,
};
const reducer = (state, action) => {
    switch (action.type) {
        case "LOGIN":
            localStorage.setItem("user", JSON.stringify(action.payload.user));
            localStorage.setItem("token", JSON.stringify(action.payload.token));
            return {
                ...state,
                isAuthenticated: true,
                user: action.payload.user,
                token: action.payload.token
            };
        case "LOGOUT":
            localStorage.clear();
            return {
                ...state,
                isAuthenticated: false,
                user: null
            };
        default:
            return state;
    }
};
const [state, dispatch] = React.useReducer(reducer, initialState);
React.useEffect(() => {
    const user = JSON.parse(localStorage.getItem('user') || null)
    const token = JSON.parse(localStorage.getItem('token') || null)

    if (user && token) {
        dispatch({
            type: 'LOGIN',
            payload: {
                user,
                token
            }
        })
    }
}, [])

class App extends React.Component {
    constructor(props) {
        super(props);
        this.service = new SystemService();
        this.state = { isloading: true, isLogin: false };
    }
    componentDidMount() { }
    componentDidCatch() { }
    componentDidUpdate() { }

    setvalue = () => {
        console.log('setvalue');
        //this.setState({ isloading: false });
        this.context.name = 'test..';
        this.forceUpdate();
    }


    render() {
        console.log('render');
        var isLoggedIn = localStorage.getItem('isLogin');
        console.log(this.service.Account);
        return (
            <AuthContext.Provider value={{ state, dispatch }}>
                <div className="jumbotron">
                    <div className="container">
                        <div className="col-sm-8 col-sm-offset-2 {process.env.REACT_APP_NOT_SECRET_CODE}">
                            <BrowserRouter>
                                <div>
                                    <div>Hello, {this.context.name} {state.isAuthenticated}</div>
                                    {isLoggedIn ?
                                        <ul>
                                            <li><NavLink id="home" activeClassName="active" to="/">Home</NavLink></li>
                                        </ul>
                                        :
                                        <ul>
                                            <li><NavLink exact activeClassName="active {isLogin}" to="/login">Login</NavLink></li>
                                            <li><NavLink activeClassName="active" to="/register">Register</NavLink></li>
                                            <li><a onClick={this.setvalue}>test</a></li>
                                        </ul>
                                    }
                                    {/*<li><NavLink id="home" activeClassName="active" to="/home">Home</NavLink></li>
                                    <li><NavLink exact activeClassName="active" to="/">Login</NavLink></li>
                                    <li><NavLink activeClassName="active" to="/register">Register</NavLink></li>*/}

                                    {/*<li><NavLink activeClassName="active" to="/home/subpage">Sub Page</NavLink></li>*/}
                                    {/*<li><NavLink activeClassName="active" to="/test">Not Found</NavLink></li>*/}
                                    <Switch>
                                        {routes.map(r => <Route key={r.path} path={r.path} exact={r.exact} component={r.component} name={r.name} />)}
                                    </Switch>
                                </div>
                            </BrowserRouter>
                        </div>
                    </div>
                </div>
            </AuthContext.Provider>
        );
    }
}

export default App;

1 Ответ

1 голос
/ 06 мая 2020

Ваш App компонент является компонентом класса, и хуки могут использоваться только внутри functional компонента.

Также вы не можете определить хуки вне области действия файла

Преобразуйте компонент приложения в функциональный компонент, как показано ниже

export const AuthContext = React.createContext();
const initialState = {
    isAuthenticated: false,
    user: null,
    token: null,
};
const reducer = (state, action) => {
    switch (action.type) {
        case "LOGIN":
            localStorage.setItem("user", JSON.stringify(action.payload.user));
            localStorage.setItem("token", JSON.stringify(action.payload.token));
            return {
                ...state,
                isAuthenticated: true,
                user: action.payload.user,
                token: action.payload.token
            };
        case "LOGOUT":
            localStorage.clear();
            return {
                ...state,
                isAuthenticated: false,
                user: null
            };
        default:
            return state;
    }
};

const AuthProvider = (props) => {

   const service = useRef(new SystemService());
        this.state = { isloading: true, isLogin: false };
    }

    const [state, dispatch] = React.useReducer(reducer, initialState);
    React.useEffect(() => {
        const user = JSON.parse(localStorage.getItem('user') || null)
        const token = JSON.parse(localStorage.getItem('token') || null)

        if (user && token) {
            dispatch({
                type: 'LOGIN',
                payload: {
                    user,
                    token
                }
            })
        }
    }, []);

    const setvalue = () => {
        console.log('setvalue');
        //this.setState({ isloading: false });
        this.context.name = 'test..';
        this.forceUpdate();
    }


    console.log('render');
    var isLoggedIn = localStorage.getItem('isLogin');
    console.log(service.Account);
    return (
        <AuthContext.Provider value={{ state, dispatch }}>
            {children}
        </AuthContext.Provider>
    );

}
const App = (props) => {
 const {state} = useContext(AuthContext);
 return (
    <div className="jumbotron">
                <div className="container">
                    <div className="col-sm-8 col-sm-offset-2 {process.env.REACT_APP_NOT_SECRET_CODE}">
                        <BrowserRouter>
                            <div>
                                <div>Hello, {state.user && state.user.name} {state.isAuthenticated}</div>
                                {isLoggedIn ?
                                    <ul>
                                        <li><NavLink id="home" activeClassName="active" to="/">Home</NavLink></li>
                                    </ul>
                                    :
                                    <ul>
                                        <li><NavLink exact activeClassName="active {isLogin}" to="/login">Login</NavLink></li>
                                        <li><NavLink activeClassName="active" to="/register">Register</NavLink></li>
                                        <li><a onClick={this.setvalue}>test</a></li>
                                    </ul>
                                }
                                {/*<li><NavLink id="home" activeClassName="active" to="/home">Home</NavLink></li>
                                <li><NavLink exact activeClassName="active" to="/">Login</NavLink></li>
                                <li><NavLink activeClassName="active" to="/register">Register</NavLink></li>*/}

                                {/*<li><NavLink activeClassName="active" to="/home/subpage">Sub Page</NavLink></li>*/}
                                {/*<li><NavLink activeClassName="active" to="/test">Not Found</NavLink></li>*/}
                                <Switch>
                                    {routes.map(r => <Route key={r.path} path={r.path} exact={r.exact} component={r.component} name={r.name} />)}
                                </Switch>
                            </div>
                        </BrowserRouter>
                    </div>
                </div>
            </div>
 )
}


export default (props) => <AuthProvider><App/></AuthProvider>;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...