statusmanagement

LearningReactstatusmanagement, includingcomponent in status, Context API, Redux, MobXetc.statusmanagementsolutions

1. component in statusmanagement

in Reactin, component in statusmanagement is 最Basics statusmanagement方式, throughuseState Hook or this.state (classcomponent) 来managementcomponent in 部 status.

1.1 usinguseState Hook

function Counter() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('');
  
  const handleIncrement = () => {
    setCount(count + 1);
  };
  
  const handleNameChange = (e) => {
    setName(e.target.value);
  };
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleIncrement}>Increment</button>
      <div>
        <input type="text" value={name} onChange={handleNameChange} placeholder="Enter your name" />
        <p>Hello, {name}!</p>
      </div>
    </div>
  );
}

1.2 usingclasscomponent state

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      name: ''
    };
  }
  
  handleIncrement = () => {
    this.setState({ count: this.state.count + 1 });
  };
  
  handleNameChange = (e) => {
    this.setState({ name: e.target.value });
  };
  
  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.handleIncrement}>Increment</button>
        <div>
          <input type="text" value={this.state.name} onChange={this.handleNameChange} placeholder="Enter your name" />
          <p>Hello, {this.state.name}!</p>
        </div>
      </div>
    );
  }
}

2. Context APIstatusmanagement

Context API允许 in componenttreein共享status, 而无需throughprops逐层传递, 适用于inetc.规模 statusmanagement.

// creationContext
const UserContext = React.createContext();

// creationProvidercomponent
function UserProvider({ children }) {
  const [user, setUser] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
  
  const login = async (email, password) => {
    setIsLoading(true);
    try {
      // mockAPIrequest
      const response = await fetch('https://api.example.com/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ email, password })
      });
      const data = await response.json();
      setUser(data.user);
    } catch (error) {
      console.error('Login error:', error);
    } finally {
      setIsLoading(false);
    }
  };
  
  const logout = () => {
    setUser(null);
  };
  
  const value = {
    user,
    isLoading,
    login,
    logout
  };
  
  return (
    <UserContext.Provider value={value}>
      {children}
    </UserContext.Provider>
  );
}

// creation自定义Hook, 方便usingContext
function useUser() {
  const context = useContext(UserContext);
  if (!context) {
    throw new Error('useUser must be used within a UserProvider');
  }
  return context;
}

// usingContext component
function LoginButton() {
  const { user, login, logout, isLoading } = useUser();
  
  const handleLogin = () => {
    login('example@example.com', 'password123');
  };
  
  if (isLoading) {
    return <button disabled>Loading...</button>;
  }
  
  if (user) {
    return (<
      >
        <p>Welcome, {user.name}!</p>
        <button onClick={logout}>Logout</button>
      </>
    );
  }
  
  return <button onClick={handleLogin}>Login</button>;
}

//  in AppcomponentinusingProvider
function App() {
  return (
    <UserProvider>
      <div>
        <LoginButton />
      </div>
    </UserProvider>
  );
}

提示

Context API适用于共享全局status, such asuserinformation, 主题设置etc..

3. Reduxstatusmanagement

Redux is a 独立 statusmanagementlibrary, 适用于 big 型 complex application statusmanagement.

3.1 Reduxcore concepts

  • Store: storeapplication 所 has status
  • Action: describesstatus变化 object
  • Reducer: 根据Actionupdatestatus function
  • Dispatch: 触发Action method
  • Selector: from Storein获取status method

3.2 usingRedux Toolkit

Redux Toolkit is 官方推荐 Reduxtool集, 简化了Redux using.

// installationRedux Toolkit
// npm install @reduxjs/toolkit react-redux

// creationSlice
import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0
  },
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    }
  }
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;

// creationStore
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';

const store = configureStore({
  reducer: {
    counter: counterReducer
  }
});

export default store;

//  in AppcomponentinusingProvider
import { Provider } from 'react-redux';
import store from './store';

function App() {
  return (
    <Provider store={store}>
      <Counter />
    </Provider>
  );
}

// usingReduxstatus component
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, incrementByAmount } from './counterSlice';

function Counter() {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
      <button onClick={() => dispatch(incrementByAmount(5))}>Increment by 5</button>
    </div>
  );
}

4. MobXstatusmanagement

MobX is 另一个流行 statusmanagementlibrary, usingresponse式programmingmodel.

// installationMobX
// npm install mobx mobx-react-lite

// creationStore
import { makeObservable, observable, action } from 'mobx';

class CounterStore {
  count = 0;
  
  constructor() {
    makeObservable(this, {
      count: observable,
      increment: action,
      decrement: action,
      incrementByAmount: action
    });
  }
  
  increment = () => {
    this.count += 1;
  };
  
  decrement = () => {
    this.count -= 1;
  };
  
  incrementByAmount = (amount) => {
    this.count += amount;
  };
}

export const counterStore = new CounterStore();

// usingMobXstatus component
import { observer } from 'mobx-react-lite';
import { counterStore } from './counterStore';

const Counter = observer(() => {
  return (
    <div>
      <p>Count: {counterStore.count}</p>
      <button onClick={counterStore.increment}>Increment</button>
      <button onClick={counterStore.decrement}>Decrement</button>
      <button onClick={() => counterStore.incrementByAmount(5)}>Increment by 5</button>
    </div>
  );
});

export default Counter;

5. statusmanagementsolutions选择

选择合适 statusmanagementsolutions取决于application 规模 and complexity:

solutions 适用场景 优点 缺点
component in status simple component, status只 in component in 部using simple 易用, 无需额 out 依赖 不适用于跨componentstatus共享
Context API inetc.规模application, 共享 few 量全局status React in 置, 无需额 out 依赖, using simple 不适用于 complex status逻辑, performance可能不佳
Redux big 型 complex application, status逻辑 complex statusmanagement集in, 易于debug and test Learning曲线陡峭, 样板code many
MobX inetc.规模application, response式programmingmodel Learning曲线平缓, performance good response式model可能导致不可预测 behavior

6. best practices

  • 优先usingcomponent in status, 只 in 必要时才using全局statusmanagement
  • 保持status尽可能 simple , 避免嵌套过深
  • using不可变dataupdatestatus, 避免直接modifystatus
  • 将status逻辑 and UIcomponent分离
  • for complex status添加TypeScriptclass型定义
  • 定期clean不再需要 status

练习 1: usingContext APImanagement主题status

  1. creation一个ThemeContext, package含dark and light两种主题
  2. implementation主题切换functions
  3. in many 个componentinusing主题status

练习 2: usingRedux Toolkitmanagement计数器status

  1. creation一个计数器Slice
  2. configurationRedux Store
  3. implementation计数器component, package含增减functions