您的位置:首页 > 新闻 > 资讯 > 网站建设个人工作室_腾讯公司_百度搜题_洛阳网站建设优化

网站建设个人工作室_腾讯公司_百度搜题_洛阳网站建设优化

2024/12/28 6:57:17 来源:https://blog.csdn.net/m0_67403143/article/details/144773847  浏览:    关键词:网站建设个人工作室_腾讯公司_百度搜题_洛阳网站建设优化
网站建设个人工作室_腾讯公司_百度搜题_洛阳网站建设优化

#题引:我认为跟着官方文档学习不会走歪路

通常来说,你会通过 props 将信息从父组件传递到子组件。但是,如果你必须通过许多中间组件向下传递 props,或是在你应用中的许多组件需要相同的信息,传递 props 会变的十分冗长和不便。Context 允许父组件向其下层无论多深的任何组件提供信息,而无需通过 props 显式传递。

假设Heading 组件接收一个level参数来决定它标题尺寸的场景

export default function Page() {return (<Section><Heading level={1}>主标题</Heading><Section><Heading level={2}>副标题</Heading><Heading level={2}>副标题</Heading><Heading level={2}>副标题</Heading><Section><Heading level={3}>子标题</Heading><Heading level={3}>子标题</Heading><Heading level={3}>子标题</Heading><Section><Heading level={4}>子子标题</Heading><Heading level={4}>子子标题</Heading><Heading level={4}>子子标题</Heading></Section></Section></Section></Section>);
}export default function Section({ children }) {return (<section className="section">{children}</section>);
}export default function Heading({ level, children }) {switch (level) {case 1:return <h1>{children}</h1>;case 2:return <h2>{children}</h2>;case 3:return <h3>{children}</h3>;case 4:return <h4>{children}</h4>;case 5:return <h5>{children}</h5>;case 6:return <h6>{children}</h6>;default:throw Error('未知的 level:' + level);}
}

这就是 context 大显身手的地方

Step 1:创建 context

创建这个 context,并 将其从一个文件中导出,这样你的组件才可以使用它

LevelContext.js

import { createContext } from 'react';export const LevelContext = createContext(1);

createContext 只需默认值这么一个参数。在这里, 1 表示最大的标题级别,但是你可以传递任何类型的值(甚至可以传入一个对象)

Step 2:使用 Context

从 React 中引入 useContext Hook 以及你刚刚创建的 context

export default function Heading({ children }) {const level = useContext(LevelContext);// ...
}

useContext 告诉 React Heading 组件想要读取 LevelContext

Step 3:提供 context

Section 组件目前渲染传入它的子组件,把它们用 context provider 包裹起来 以提供 LevelContext 给它们

import { LevelContext } from './LevelContext.js';export default function Section({ level, children }) {return (<section className="section"><LevelContext.Provider value={level}>{children}</LevelContext.Provider></section>);
}

这告诉 React:“如果在 Section组件中的任何子组件请求 LevelContext,给他们这个 level。”组件会使用 UI 树中在它上层最近的那个 <LevelContext.Provider> 传递过来的值。

由于 context 让你可以从上层的组件读取信息,每个 Section 都会从上层的 Section 读取 level,并自动向下层传递 level + 1。
你可以像下面这样做:

import { useContext } from 'react';
import { LevelContext } from './LevelContext.js';export default function Section({ children }) {const level = useContext(LevelContext);return (<section className="section"><LevelContext.Provider value={level + 1}>{children}</LevelContext.Provider></section>);
}

这样修改之后,你不用将 level 参数传给 Section>或者是 Heading

export default function Page() {return (<Section><Heading>主标题</Heading><Section><Heading>副标题</Heading><Heading>副标题</Heading><Heading>副标题</Heading><Section><Heading>子标题</Heading><Heading>子标题</Heading><Heading>子标题</Heading><Section><Heading>子子标题</Heading><Heading>子子标题</Heading><Heading>子子标题</Heading></Section></Section></Section></Section>);
}

在 React 中,覆盖来自上层的某些 context 的唯一方法是将子组件包裹到一个提供不同值的 context provider 中

Context 的使用场景
  • 主题: 如果你的应用允许用户更改其外观
  • 当前账户: 许多组件可能需要知道当前登录的用户信息
  • 路由: 大多数路由解决方案在其内部使用 context 来保存当前路由
  • 状态管理: 随着你的应用的增长,最终在靠近应用顶部的位置可能会有很多 state。许多遥远的下层组件可能想要修改它们。通常 将 reducer 与 context 搭配使用来管理复杂的状态并将其传递给深层的组件来避免过多的麻烦。

Context 不局限于静态值。如果你在下一次渲染时传递不同的值,React 将会更新读取它的所有下层组件。

useContext与与useState结合

1: 创建 Context 和 Provider 组件:
使用 Provider 来包裹需要访问这个上下文的组件,并提供一个状态来管理上下文的值

import React, { createContext, useState } from 'react';const MyContext = createContext();
const MyProvider = ({ children }) => {const [value, setValue] = useState("初始值");return (<MyContext.Provider value={{ value, setValue }}>{children}</MyContext.Provider>);
};

2: 使用 useContext:
在子组件中使用 useContext 来访问上下文的值和变更函数

import React, { useContext } from 'react';const MyComponent = () => {const { value, setValue } = useContext(MyContext);const changeValue = () => {setValue("新值");};return (<div><p>当前值: {value}</p><button onClick={changeValue}>变更值</button></div>);
};

3: 包裹应用

const App = () => {return (<MyProvider><MyComponent /></MyProvider>);
};
useContext与与useReducer结合

1: 定义 Reducer 函数

const initialState = { count: 0 };const reducer = (state, action) => {switch (action.type) {case 'increment':return { count: state.count + 1 };case 'decrement':return { count: state.count - 1 };default:return state;}
};

2:创建 Context 和 Provider 组件
使用 useReducer 在 Provider 中管理状态,并将状态和 dispatch 方法提供给上下文

import React, { createContext, useReducer } from 'react';const MyContext = createContext();const MyProvider = ({ children }) => {const [state, dispatch] = useReducer(reducer, initialState);return (<MyContext.Provider value={{ state, dispatch }}>{children}</MyContext.Provider>);
};

3:使用 Context 和 Reducer
在子组件中使用 useContext 来访问状态和 dispatch 方法

const Counter = () => {const { state, dispatch } = useContext(MyContext);return (<div><p>计数: {state.count}</p><button onClick={() => dispatch({ type: 'increment' })}>增加</button><button onClick={() => dispatch({ type: 'decrement' })}>减少</button></div>);
};

4:包裹应用

const App = () => {return (<MyProvider><MyComponent /></MyProvider>);
};

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com