本次课程我们来实现我们mini react项目中的useState.
期望实现的效果
- app.js
tsx
import React from "./core/React.js";
function Foo() {
const [count, setCount] = React.useState(10)
function handleClick() {
setCount((prevCount) => prevCount + 1)
}
return (
<div>
<h1>foo</h1>
{count}
<button onClick={handleClick}>click</button>
</div>
);
}
function Bar() {
const [count, setCount] = React.useState(10)
function handleClick() {
setCount((prevCount) => prevCount + 1)
}
return (
<div>
<h1>bar</h1>
{count}
<button onClick={handleClick}>click</button>
</div>
);
}
function App() {
return (
<div>
<Foo></Foo>
</div>
);
}
export default App;
能正常展示出数据
tsx
function useState(initial) {
const stateHook = {
state: initial
}
function setState(action) {
stateHook.state = action
}
return [stateHook.state, setState]
}
const React = {
render,
useState,
createElement,
update
}
实现数据的修改
tsx
function useState(initial) {
let currentFiber = wipFiber;
const oldHook = currentFiber.alternate?.stateHook
const stateHook = {
state: oldHook?.state || initial
}
currentFiber.stateHook = stateHook
function setState(action) {
stateHook.state = action(stateHook.state)
wipRoot = {
...currentFiber,
alternate: currentFiber
}
nextWorkOfUnit = wipRoot
}
return [stateHook.state, setState]
}

实现多个hooks的情况
- app.js
tsx
import React from "./core/React.js";
function Foo() {
const [count, setCount] = React.useState(10)
const [bar, setBar] = React.useState('bar')
function handleClick() {
setCount((prevCount) => prevCount + 1)
setBar((prevBar) => prevBar + 'bar')
}
return (
<div>
{count}
{bar}
<button onClick={handleClick}>click</button>
</div>
);
}
function Bar() {
const [count, setCount] = React.useState(10)
function handleClick() {
setCount((prevCount) => prevCount + 1)
}
return (
<div>
<h1>bar</h1>
{count}
<button onClick={handleClick}>click</button>
</div>
);
}
function App() {
return (
<div>
<Foo></Foo>
</div>
);
}
export default App;
现在出现问题,这是因为现在就用了一个Hook

改成数组
tsx
function updateFunctionComponent(fiber) {
stateHooks = []
stateHookIndex = 0
wipFiber = fiber
const children = [fiber.type(fiber.props)]
reconcileChildren(fiber, children)
}
let stateHooks
let stateHookIndex
function useState(initial) {
let currentFiber = wipFiber;
const oldHook = currentFiber.alternate?.stateHooks[stateHookIndex]
const stateHook = {
state: oldHook ? oldHook.state : initial
}
stateHookIndex++
stateHooks.push(stateHook)
currentFiber.stateHooks = stateHooks
function setState(action) {
stateHook.state = action(stateHook.state)
wipRoot = {
...currentFiber,
alternate: currentFiber
}
nextWorkOfUnit = wipRoot
}
return [stateHook.state, setState]
}
现在正常了
