跨层级数据传输
context的应用
第一步创立context对象
const MyContext = React.createContext();export default MyContext;第二步应用provider传递数据
export default const Index = (props) => { const [data] = React.useState({}); return <MyContext.Provider value={data}> {prop.children} </MyContext.Provider>};留神这里的data应该是Index组件的一个状态,防止因为每次Index刷新,data从新是生成,导致子组件也diff,具体解释。
- 子孙组件生产value
生产context的值有三种形式; - contextType
class MyClass extends React.Component { componentDidMount() { let value = this.context; /* 在组件挂载实现后,应用 MyContext 组件的值来执行一些有副作用的操作 */ } componentDidUpdate() { let value = this.context; /* ... */ } componentWillUnmount() { let value = this.context; /* ... */ } render() { let value = this.context; /* 基于 MyContext 组件的值进行渲染 */ }}MyClass.contextType = MyContext;留神:你只通过该 API 订阅繁多 context。如果你想订阅多个,请应用Cunsumer。如果你正在应用实验性的 public class fields 语法,你能够应用static这个类属性来初始化你的contextType。
class MyClass extends React.Component { static contextType = MyContext; render() { let value = this.context; /* 基于这个值进行渲染工作 */ }}Cunsumer
<MyContext.Consumer> {value => /* 基于 context 值进行渲染*/}</MyContext.Consumer>这种办法须要一个函数作为子元素(function as a child)。这个函数接管以后的 context 值,并返回一个 React 节点。传递给函数的
value值等价于组件树上方离这个 context 最近的 Provider 提供的value值。如果没有对应的 Provider,value参数等同于传递给createContext()的defaultValue。- useContext
应用比较简单, 然而只能在hook语法中应用:
function ShowAn(){//调用useContext,传入从MyContext获取的上下文对象。 const value = useContext(MyContext); return( <div> the answer is {value} </div> )更加粗疏的内容能够参照react官网给出的文档
公布订阅模式
这个就不陈词滥调了,懂的都懂,简略点说就是在订阅阶段将数据压入到队列中,公布的时候在遍历下这个队列取出想要的后果进行操作;
这里想说的是,到编写公布订阅这个模式的代码是咱们应该留神到的一个细节就是,与订阅成对呈现的还有一个就是勾销订阅,只有写了勾销订阅的程序才会在肯定水平上失去优化。
咱们能够再订阅阶段的函数中在push阶段的函数中这样操作,
const subscribe = (data) => { Array.push(data); return () => { Array = Array.filter(item => item !== data); }}// 而后在订阅函数调用的中央这样写const unsubscribe = subscribe(data);当咱们想要勾销订阅的时候间接调用unsubscribe()即可是不是很不便呢!认真看一下是不是很像是hook语法中useEffect的应用形式。
另外再说一点
明天看到一个有意思的博客,次要说异步中断的问题,一开始在说jq的ajax、axios,以及fetch的超时问题,后面的都比较简单,ajax有.abort()函数, axios原本就存在time字段,fetch也是能够中断的,只需一个AbortController对象获取signal,并将这个信号对象作为fetch的选项传入。
async function fetchWithTimeout(timeout, resoure, init = {}) { const ac = new AbortController(); const signal = ac.signal; const timer = setTimeout(() => { console.log("It's timeout"); return ac.abort(); }, timeout); try { return await fetch(resoure, { ...init, signal }); } finally { clearTimeout(timer); }}重点来了(敲黑板画知识点),万物皆可超时,Axios 和 fetch 都提供了中断异步操作的路径,但对于一个不具备 abort 能力的一般 Promise 来说,该怎么办?
文中给了一个很奇妙的解决办法;
Promise尽管没有abort能力然而咱们想要对其进行超时中断能够利用.race办法,race 是竞速的意思,所以 Promise.race() 的行为是不是很好了解?
function waitWithTimeout(promise, timeout, timeoutMessage = "timeout") { let timer; const timeoutPromise = new Promise((_, reject) => { timer = setTimeout(() => reject(timeoutMessage), timeout); }); return Promise.race([timeoutPromise, promise]) .finally(() => clearTimeout(timer)); // 别忘了清 timer}