간단히 말하면 React 프로젝트에서 Redux 구현

32764 단어 reactboilerplateredux
비록 나는 지금 신분 검증을 배우고 있지만, Redux는 내가 어떤 React 프로젝트에서도 쉽게 벗어날 수 없는 것이다. 왜냐하면 상태 관리가 매우 중요하기 때문이다.이번에 내가 완전한 창고 프로젝트를 위해 처음부터 Redux를 설정할 때, 나는 목록을 만들거나 Redux를 프로젝트에 추가할 때 해야 할 일을 더 참고하고 싶다.

이거 뭐 아니야?


이 글은 절대 Redux의 초보자 안내서가 아니며, CRUD 중심의 응용 프로그램을 만드는 연습도 아니다.내가 이 글을 쓴 것은 단지 내가 첫눈에 Redux를 본 후에 쓰기 시작했기 때문이다. 그러나 그 이후로 나의 관점에 변화가 생겼다. 특히 내가 이전에 그것을 사용했기 때문이다.
조직적인 방식으로 Redux를 실현하고자 하는 모든 사람들의 검사표가 되기를 바랍니다.언제든지 논평에서 의견을 발표해 주십시오.

입문


우선, 우리는 기계에서 CRA 템플릿으로 새로운 프로젝트를 시작합니다.
npx create-react-app redux-demo-setup
지금 편집기에서 그것을 열고 글을 계속 훑어보십시오.
솔직히 말하면, 내가 프로젝트를 세운 후에 한 첫 번째 일은 바로 상태 관리 라이브러리를 추가하는 것이 아니다. 왜냐하면 이것은 비용을 증가시키고 시작할 때 진도를 늦출 수 있기 때문이다.
초기 상태 관리를 처리하는 방법은 다음과 같습니다.
  • 아이템을 통한 상용 방식
  • React 자체 컨텍스트 API
  • 선언되지 않음, 내부적으로 컨텍스트를 사용하여 간단하게 상태 관리
  • 물론, 나는 이 모든 절차를 반복하지 않을 것이다. 왜냐하면 당신들이 이곳에 온 것은 당신들의 프로젝트에 Redux를 설정하는 방법을 알고 싶어서이다.

    redux의 사진 한 장 빠른 회고



    Modern React with Redux에서 온 필터 뚜껑.

    어디서부터 시작해요?


    따라서, 기본적으로 우리가 응용 프로그램에 Redux를 설정할 때, 우리가 해야 할 일은 바로 이것들이다.
  • 글로벌 스토어 구축
  • 스토리지 객체를 업데이트하기 위한 여러 개의 복원기
  • 동작 창조자에게 특정한 일을 시키다
  • 비동기식 작업에 중간부품 추가(예:thunk)
  • 패키지를 사용하여 Redux를 응용 프로그램에 연결
  • 함수
  • 내의 Redux 개발 도구 코드 세그먼트 포함
    이것은 Redux 설정을 완성하기 위해 우리가 취할 절차입니다.

    필요한 소프트웨어 패키지 설치


    우리가 진일보한 토론을 하기 전에, 나는 항상 우리가 일치되기를 희망하기 때문에, 우리가 필요로 하는 모든 소프트웨어 패키지를 설치하는 것부터 시작하자.
    npm install redux react-redux redux-thunk
    
    또는
    yarn add redux react-redux redux-thunk
    

    reactredux 만들기


    Redux의 궁극적인 기능은 모든 데이터가 있는 곳에 저장되는 것입니다.이것부터 시작합시다.내 프로젝트에서, 나는 주 관리와 관련된 모든 파일을 이 디렉터리에 두기를 바란다. createStore() 폴더에 모든 내용을 추가할 수 있지만, 나는 이렇게 저장하는 것을 좋아한다. 이렇게 하면 질서정연하게 유지할 수 있다.store.js 내에 src/redux 라는 파일을 만듭니다.
    import { createStore, applyMiddleware, compose } from "redux";
    import thunk from "redux-thunk";
    
    // We'll make this file soon
    import rootReducer from "./reducers/index";
    
    const middleware = [thunk];
    const initialState = {};
    
    const store = createStore(
      rootReducer,
      initialState,
      compose(
        applyMiddleware(...middleware),
        window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
      )
    );
    
    export default store;
    
    이것은 src 중의 createStore function 을 사용하여 우리를 위해 상점을 직접 만들 것이다.루트 감속기는 파일입니다. 모든 감속기를 합쳐서 다음 단계에서 만들 것입니다.
    applyMiddleware 함수는 thunk 을 중간부품으로 포함하고 있으며, 현재 우리는 동작 창설자에서 그것을 사용할 수 있다.코드 세그먼트를 어떻게 추가하는지 보십시오. 이것은 유명한 Redux 개발 도구가 저희 browser extension 에서 실행될 수 있도록 합니다. (아래 참조)

    여러 개의 감속기와 루트 감속기 만들기


    이를 위해, 우리는 store.js 폴더 중 하나src/redux 폴더를 가지고 있으며, 이렇게 하면 우리는 모든 감속기를 안에 넣을 수 있다.우리는 그 중에서 redux 파일을 만들어서 모든 감속기를 합쳐서 위의 window.__REDUX_DEVTOOLS... 파일에 제공할 것이다.
    우리는 이곳에서 어떤 특정한 프로젝트도 하지 않았기 때문에 메시지를 전달하기 위해 두 개의 가상 복원기, 즉.reducersredux.그리고 index.js를 생성하여 결합합니다.store.js이 어떤 모습인지 봅시다.
    import { SET_CURRENT_USER } from "./../actions/types";
    import _ from "lodash";
    
    const initialState = {
      isAuthenticated: false,
      user: {},
    };
    
    const reducer = (state = initialState, action) => {
      switch (action.type) {
        case SET_CURRENT_USER:
          return {
            ...state,
            isAuthenticated: !_.isEmpty(action.payload),
            user: action.payload,
          };
        default:
          return state;
      }
    };
    
    export default reducer;
    
    감속기 함수의 세부 사항에 지나치게 관심을 가지지 마라. 왜냐하면 이것은 단지 감속기의 외관을 가시화하기 위해서이기 때문이다.
    우리가 여기서 하는 일은 authReducer.js 파일에서 형식을 가져오는 것입니다. 우리는 1분 안에 errorReducer.js 을 생성하고 이 동작을 스케줄링할 때 수정된 상태를 되돌려줍니다.
    이와 유사하게, 우리는 index.js 동작 창설자 내부의 오류를 처리할 수 있습니다.
    지금 이 두 개의 감속기를 계속 결합하면 우리는 새로 만든 authReducer.js 파일로 옮길 것이다. 이것이 바로 그 중에서 발생한 일이다.
    import { combineReducers } from "redux";
    import authReducer from "./authReducer";
    import errorReducer from "./errorReducer";
    
    export default combineReducers({
      auth: authReducer,
      errors: errorReducer,
    });
    
    따라서 현재 types.js 에서 얻은 상태는 우리 구성 요소의 SET_CURRENT_USER 에 접근할 수 있으며, 또한 오류가 있을 수 있습니다.현재 메인 감속기 파일이 있기 때문에, 오류가 발생하지 않고 errorReducer.js 에서 가져올 수 있습니다.

    우리의 행동과 유형을 만들다


    현재, 매번 우리가 동작을 실행하거나 스케줄링해야 할 때, 우리는 그것을 우리의 React 구성 요소에 난잡하게 놓아서는 안 된다. 따라서 우리는 그것들을 동작 창설자로서 하나의 단독 위치에 놓아야 한다. 모든 구성 요소에서 쉽게 스케줄링할 수 있다.
    이미 알고 있는 바와 같이, 디스패치에 전달할 형식이 있어야 합니다. 따라서 우선 문자열을 형식에 직접 전달하는 것이 아니라 조직적인 방식으로 만들 것입니다.index.js 폴더에 authReducer 라는 파일을 만듭니다. 이 파일은 props.auth 폴더에 있습니다.그게 그 내용입니다.
    export const GET_ERRORS = "GET_ERRORS";
    export const CLEAR_ERRORS = "CLEAR_ERRORS";
    export const SET_CURRENT_USER = "SET_CURRENT_USER";
    
    이것들은 단지 일반적인 유형일 뿐, 필요에 따라 모든 유형을 추가할 수 있다는 것을 기억하십시오.
    작업이라면 React 구성 요소에 접근해야 할 수 있는 임의의 작업을 만들 수 있습니다. 예를 들어 사용자 등록, 로그인, 로그아웃, 데이터 얻기 등입니다.그러나, 나는 너희들에게 어떻게 너희들의 동작 창조자를 조직하는지 보여줄 것이다
    import axios from "axios";
    import jwt_decode from "jwt-decode";
    import { GET_ERRORS, SET_CURRENT_USER } from "./types";
    
    // Login - Get user Token
    export const loginUser = userData => dispatch => {
      axios
        .post("/api/users/login", userData)
        .then(res => {
          // Save to local storage
          const { token } = res.data;
    
          // Set item to localstorage
          localStorage.setItem("jwtToken", token);
    
          // Decode token to get user data
          const decoded = jwt_decode(token);
    
          // Set current user
          dispatch({ type: SET_CURRENT_USER, payload: decoded });
        })
        .catch(err => dispatch({ type: GET_ERRORS, payload: err.response.data }));
    };
    
    // Log user out
    export const logoutUser = () => dispatch => {
      // Remove token from localstorage
      localStorage.removeItem("jwtToken");
    
      // Set current to empty object which will set isAuth to false
      dispatch({ type: SET_CURRENT_USER, payload: {} });
    };
    
    자세히 보면, 이곳의 동작 생성기는 간단한 함수가 아니라, 다른 전달 매개 변수 store.js 를 되돌려주는 함수입니다.이것이 바로 Reduxthunk가 우리에게 제공하는 기능이다.
    이것은 우리 자신의 Dan Abramov가 왜 types.jsstackoverflow에서 비동기 동작 생성기를 만들어야 하는지에 대한 매우 깊은 해석이다.
    Why do we need middleware for async flow in Redux?
    간단히 말하면, 당신은 항상 어떤 중간부품Thunk이나 Saga을 사용하여 우리의 동작 생성기에서 비동기적인 요청을 처리하기를 원합니다.그렇지 않으면, 디스패치를 동작 생성자에게 매개 변수로 전달해서 구성 요소를 엉망으로 만들어야 합니다. 이것은 구성 요소가 걱정해야 할 것이 아닙니다.마찬가지로 위의 게시물은 나보다 훨씬 명확하게 해석되었다.

    작업을 사용하여 애플리케이션에 Redux 스토리지 접속


    이것이 바로 소프트웨어 패키지src/redux의 작업 원리다.이것은 우리의 dispatch 대상을 그것의 Provider API에 분배하는데, 이것은 우리가 응용 프로그램의 어느 위치에서든 전역 저장소에 접근할 수 있도록 한다.
    내가'응용 프로그램의 어느 곳에서든 상점을 방문할 수 있다'고 말하는 것은 네가 이렇게 해야 한다는 것을 의미하지는 않지만, 이것은 선호하는 문제이다.나는 구성 요소를 계속 만들었다. 이 구성 요소들은 나의 redux-thunk 용기와 구성 요소 폴더로 분리되었다.구성 요소와 용기 구성 요소를 표시하고 용기 구성 요소만 전역 저장소에 접근하여 표현 구성 요소에 전달할 수 있다는 것을 알 수 있습니다.이 모드는 Dan's Medium Post 에서 확인할 수 있습니다.
    좋습니다. 프로그램 루트 디렉터리에 Redux의 공급자 API에 응답하기 위해store 대상을 추가하는 방법입니다.react-redux
    import React, { Component } from "react";
    import { Provider } from "react-redux";
    
    import store from "./redux/store";
    
    class App extends Component {
      render() {
        return (
          <Provider store={store}>
            <div className="App">
              <Navbar />
              <Main />
              <Footer />
            </div>
          </Provider>
        );
      }
    }
    
    export default App;
    
    어플리케이션의 무결성 주위에 react-redux 패키지를 배치하여 언제 어디서나 어플리케이션 스토어에 액세스할 수 있도록 합니다.

    어셈블리에서 상태 액세스


    응용 프로그램에 store 라는 구성 요소가 있다고 가정하면 전역 저장 대상에서 src 상태에 접근해야 합니다.우리는 이렇게 했다.
    import React, { Component } from "react";
    import PropTypes from "prop-types";
    
    import { connect } from "react-redux";
    import { loginUser } from "./../redux/actions/authActions";
    
    class Login extends Component {
      constructor() {
        super();
        this.state = {
          email: "",
          password: "",
        };
      }
    
      // this.props.auth = {
      //        isAuthenticated: false,
      //        user: {},
      //    };
    
      componentDidMount() {
        // check if authenticated (then redirect to dashboard)
        if (this.props.auth.isAuthenticated) this.props.history.push("/dashboard");
      }
    
      changeHandler = e => this.setState({ [e.target.name]: e.target.value });
    
      submitHandler = e => {
        e.preventDefault();
    
        const userData = {
          email: this.state.email,
          password: this.state.password,
        };
    
        // calling the action
        this.props.loginUser(userData);
      };
    
      render() {
        return (
          <div className="login">
            <form onSubmit={this.submitHandler}>
              <input
                type="email"
                name="email"
                value={this.state.email}
                onChange={this.changeHandler}
              />
              <input
                type="email"
                name="email"
                value={this.state.email}
                onChange={this.changeHandler}
              />
              <button type="submit">Submit</button>
            </form>
          </div>
        );
      }
    }
    
    Login.propTypes = {
      loginUser: PropTypes.func.isRequired,
      auth: PropTypes.object.isRequired,
    };
    
    const mapStateToProps = state => ({
      auth: state.auth,
    });
    
    export default connect(mapStateToProps, { loginUser })(Login);
    
    나는 네가 이미 코드를 완전히 읽었으면 좋겠다.따라서 구성 요소의 상태와 동작 작성자에 접근할 때 두 가지를 고려해야 한다.
  • 부터App.js가져오기Provider
  • import { connect } from "react-redux";
    
  • 선언된 위치에서 필요한 동작 작성자 가져오기
  • import { loginUser } from "./../redux/actions/authActions";
    
  • 그림과 같이 어셈블리의 Login.jsx선을 수정합니다.
  • export default connect(mapStateToProps, {
      /* action creators */
    })(Login);
    
  • 함수를 성명합니다. 이 함수는 우리가 필요로 하는 모든 저장 대상에 접근하여 우리의 도구에 포함시킬 수 있습니다.
  • const mapStateToProps = state => ({
      auth: state.auth,
    });
    
    보시다시피 저희는 auth 에서 connect 사용자에게 인증을 받았는지 확인하기 위해 react-redux 루트에 접근했습니다. 이것은 export default 함수를 통해 이루어질 수 있습니다.
  • 동작 생성자를connect 함수에 전달
  • export default connect(mapStateToProps, { loginUser })(Login);
    
    mapStateToProps와 유사하게 가져온 동작 생성기this.props.authcomponentDidMount()의 두 번째 매개 변수로 대상에 전달할 때 /dashboard에서 직접 접근할 수 있습니다.따라서 우리는 호출 mapStateToProps 을 통해 mapStateToProps 함수에 접근할 수 있다.loginUser 매개변수로 동작 작성자에게 전달됩니다.

    프로덕션에서 Redux 개발 도구 제거


    이것은 일종의 선호이다.그것은 통상적으로 개발에서 사용되는데, 만약 당신이 생산 중에도 그것을 사용하고 싶다면, 참고로 그것website을 확인해 주십시오. 저도 이 글을 잘 들었습니다explains its use in production.
    한 번은 생산 과정에서 오류가 발생했습니다. 제 사이트는 간단하게 불러올 수 없습니다. 저는 공백 화면을 주었습니다. 나중에 이것은 제가 생산 구축에서 이redux 개발 도구를 배제한 것을 잊어버렸기 때문이라는 것을 깨달았습니다.이것이 바로 네가 할 수 있는 것이다.
    const devTools =
      process.env.NODE_ENV === "production"
        ? compose(applyMiddleware(...middleware))
        : compose(
            applyMiddleware(...middleware),
            window.__REDUX_DEVTOOLS_EXTENSION__ &&
              window.__REDUX_DEVTOOLS_EXTENSION__()
          );
    
    const store = createStore(rootReducer, initialState, devTools);
    

    의견은 매우 가치가 있다


    이 글을 끝낼 때 어떤 의견이 있으면 댓글로 공유하거나 트위터를 보내야 도움이 된다고 말하고 싶습니다.이렇게 오래 같이 있어줘서 고마워요, 나중에 봐요!🌠

    좋은 웹페이지 즐겨찾기