Skip to content

Commit c38c2a0

Browse files
authored
feat: 内置 create-react-context 依赖以消除 peer 警告
1 parent 24d97ee commit c38c2a0

4 files changed

Lines changed: 138 additions & 4 deletions

File tree

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,9 @@
4040
"react": ">=16"
4141
},
4242
"dependencies": {
43-
"create-react-context": "^0.3.0",
4443
"hoist-non-react-statics": "^3.3.0",
4544
"react-node-key": "^0.4.0",
46-
"szfe-tools": "^0.0.0-beta.7"
45+
"szfe-tools": "npm:@fexd/tools@^0.1.6"
4746
},
4847
"devDependencies": {
4948
"@babel/core": "^7.5.5",

src/core/Bridge/Context/fixContext.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useContext, Fragment } from 'react'
2-
import createReactContext from 'create-react-context'
32
import { run, get, isString, isFunction, memoize, EventBus, isExist } from 'szfe-tools'
43

4+
import createReactContext from '../../../helpers/createReactContext'
55
import { aliveScopeContext, aliveNodeContext } from '../../context'
66

77
export const fixedContext = []

src/core/context/reactContext.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import createContext from 'create-react-context'
1+
import createContext from '../../helpers/createReactContext'
22

33
// 整个 KeepAlive 功能的上下文,将 KeepAlive 的组件藏于其 Provider 中,保证其不会被卸载
44
export const aliveScopeContext = createContext()

src/helpers/createReactContext.js

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// From https://github.com/jamiebuilds/create-react-context/blob/master/src/implementation.js
2+
import React, { Component } from 'react'
3+
import { random } from 'szfe-tools'
4+
5+
const MAX_SIGNED_31_BIT_INT = 1073741823
6+
7+
// Inlined Object.is polyfill.
8+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
9+
function objectIs(x, y) {}
10+
11+
function createEventEmitter(value) {
12+
let handlers = []
13+
return {
14+
on(handler) {
15+
handlers.push(handler)
16+
},
17+
18+
off(handler) {
19+
handlers = handlers.filter((h) => h !== handler)
20+
},
21+
22+
get() {
23+
return value
24+
},
25+
26+
set(newValue, changedBits) {
27+
value = newValue
28+
handlers.forEach((handler) => handler(value, changedBits))
29+
},
30+
}
31+
}
32+
33+
function onlyChild(children) {
34+
return Array.isArray(children) ? children[0] : children
35+
}
36+
37+
function createReactContext(defaultValue, calculateChangedBits) {
38+
const contextProp = '__create-react-context-' + random() + '__'
39+
40+
class Provider extends Component {
41+
emitter = createEventEmitter(this.props.value)
42+
43+
getChildContext() {
44+
return {
45+
[contextProp]: this.emitter,
46+
}
47+
}
48+
49+
componentWillReceiveProps(nextProps) {
50+
if (this.props.value !== nextProps.value) {
51+
let oldValue = this.props.value
52+
let newValue = nextProps.value
53+
let changedBits
54+
55+
if (objectIs(oldValue, newValue)) {
56+
changedBits = 0 // No change
57+
} else {
58+
changedBits =
59+
typeof calculateChangedBits === 'function'
60+
? calculateChangedBits(oldValue, newValue)
61+
: MAX_SIGNED_31_BIT_INT
62+
63+
changedBits |= 0
64+
65+
if (changedBits !== 0) {
66+
this.emitter.set(nextProps.value, changedBits)
67+
}
68+
}
69+
}
70+
}
71+
72+
render() {
73+
return this.props.children
74+
}
75+
}
76+
77+
class Consumer extends Component {
78+
observedBits
79+
80+
state = {
81+
value: this.getValue(),
82+
}
83+
84+
componentWillReceiveProps(nextProps) {
85+
let { observedBits } = nextProps
86+
this.observedBits =
87+
observedBits === undefined || observedBits === null
88+
? MAX_SIGNED_31_BIT_INT // Subscribe to all changes by default
89+
: observedBits
90+
}
91+
92+
componentDidMount() {
93+
if (this.context[contextProp]) {
94+
this.context[contextProp].on(this.onUpdate)
95+
}
96+
let { observedBits } = this.props
97+
this.observedBits =
98+
observedBits === undefined || observedBits === null
99+
? MAX_SIGNED_31_BIT_INT // Subscribe to all changes by default
100+
: observedBits
101+
}
102+
103+
componentWillUnmount() {
104+
if (this.context[contextProp]) {
105+
this.context[contextProp].off(this.onUpdate)
106+
}
107+
}
108+
109+
getValue() {
110+
if (this.context[contextProp]) {
111+
return this.context[contextProp].get()
112+
} else {
113+
return defaultValue
114+
}
115+
}
116+
117+
onUpdate = (newValue, changedBits) => {
118+
const observedBits = this.observedBits | 0
119+
if ((observedBits & changedBits) !== 0) {
120+
this.setState({ value: this.getValue() })
121+
}
122+
}
123+
124+
render() {
125+
return onlyChild(this.props.children)(this.state.value)
126+
}
127+
}
128+
129+
return {
130+
Provider,
131+
Consumer,
132+
}
133+
}
134+
135+
export default React.createContext || createReactContext

0 commit comments

Comments
 (0)