Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.2k views
in Technique[技术] by (71.8m points)

react hooks useCallback问题?

`

const [step, setStep] = useState(0);
const [count, setCount] = useState(0);
const handleSetStep = () => {
    setStep(step + 1);
};
const handleSetCount = () => {
    setCount(count + 1);
};
const lazyCallback = useCallback(() => {
    console.log('lazy callback');
     return step
}, [step]);

return (
    <div>
        <button onClick={handleSetStep}>step is : {step} </button>
        <button onClick={handleSetCount}>count is : {count} </button>
        <hr />
        <Child cb={lazyCallback} /> <hr />
    </div>
);

`

Childs.jsx
`

export default (props = {}) => {
    console.log(`--- re-render ---`);
    return (
        <div>
            <p>number is : {props.cb()}</p>
        </div>
    );
};
    

`

lazyCallback只依赖step的变化而变化,为什么我修改count, Child依旧会更新?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Child依旧会更新,是因为你以这样的形式写jsx

<div>
    <button onClick={handleSetStep}>step is : {step} </button>
    <button onClick={handleSetCount}>count is : {count} </button>
    <hr />
    <Child cb={lazyCallback} /> <hr />
</div>

Child最终会被babel编译为React.createElement的调用。那么再看一下React.createElement的源码:

export function createElement(type, config, children) {
  // 重点在这里,重新声明了props属性的引用
  const props = {};
  ...
  return ReactElement(
    type,
    key,
    ref,
    self,
    source,
    ReactCurrentOwner.current,
    props,
 );
}

它每次执行,都会重新声明一下props,直接导致了Child的props发生变化。所以即使没有改变和Child有关的props,但由于props重新声明了,所以props还是变了,所以重新更新。但只是执行了一下render,并没有往下走,这就是diff算法起的作用


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...