안녕하세요 저는 감정 제공자 테마의 두 가지 테마를 가진 테마 제공자를 가지고 있습니다.
useTheme를 통해이 테마를 얻는 구성 요소 Header가 있습니다.
const Header = () => {
const Theme = useTheme();
const [text, setText] = useState('');
console.log(Theme, 'this is header');
const handleClick = () => {
setText('');
};
return (
<Container theme={Theme}>
<Content theme={Theme} flexdirection={'column'}>
<textarea
onKeyPress={e => {
if (e.key === 'Enter') {
e.preventDefault();
}
if (e.key === 'Enter') {
handleClick();
}
}}
value={text}
onChange={e => setText(e.target.value)}
placeholder="Digite aqui sua mensagem"
/>
<Top theme={Theme} />
<NavBar theme={Theme} />
</Content>
</Container>
);
};
그런 다음 내 테마를 어린이를위한 소품으로 전달합니다.
const NavBar = props => {
console.log(props.theme, 'this is nav bar');
return (
<Nav>
<ul>
<li>
<a href="#home">home</a>
</li>
<li>
<a href="#homex">test</a>
</li>
<li>
<a href="#homexv">test</a>
</li>
</ul>
</Nav>
);
};
그러나이 구성 요소에는 입력 할 때 렌더링 할 텍스트 필드가 있지만 내 테마는 gif에서와 같이 함께 렌더링됩니다.
테마를 제어하는 방법은 다음과 같습니다.
export default function useAppTheme(defaultTheme = lightTheme) {
const [theme, _setTheme] = useState(getInitialTheme);
function getInitialTheme() {
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'dark' || savedTheme === 'light') {
return JSON.parse(savedTheme) === 'dark' ? darkTheme : defaultTheme;
} else {
return defaultTheme;
}
}
useEffect(() => {
localStorage.setItem('theme', JSON.stringify(theme.type));
}, [theme]);
return {
theme,
setTheme: ({ setTheme, ...theme }) => {
if (theme.type === 'dark') {
return _setTheme(darkTheme);
} else {
return _setTheme(lightTheme);
}
},
};
}
내 주요 구성 요소 :
export default function App() {
const { theme, setTheme } = useAppTheme();
useEffect(() => {
console.log('rendering app');
});
return (
<ThemeProvider theme={theme}>
<GlobalStyle />
<div className="App">
<Header />
<button
css={css`
background: red;
width: 100px;
height: 50px;
border-radius: 10px;
`}
onClick={() =>
setTheme(
theme.type === 'dark' ? { type: 'light' } : { type: 'dark' },
)
}
>
a
</button>
</div>
</ThemeProvider>
내가 이해했듯이 코드가 예상대로 작동합니다. 다음과 같이 설명 할 수있을 것 같습니다.
Header
상태 업데이트 ( setText
onChange 호출 )로 인해 다시 렌더링됩니다 . 컴포넌트가 다시 렌더링되면 모든 하위 컴포넌트는 다시 렌더링해야합니다 (props가 변경되지 않더라도). 또는 구성 요소를 사용 shouldComponentUpdate
하거나 사용하여이 다시 렌더링에서 옵트 아웃 할 수 있습니다 . 여기서 볼 수 있듯이 상태 기능 구성 요소 일 뿐이며 모든 상태 업데이트시 다시 렌더링됩니다. 자세한 내용은 여기 를 참조하십시오.PureComponent
memoized function(al)
NavBar
React.memo
다음과 같이이 문제를 해결할 수 있습니다 .
const NavBar = React.memo(props => {
console.log(props.theme, 'this is nav bar');
return (
<Nav>
<ul>
<li>
<a href="#home">home</a>
</li>
<li>
<a href="#homex">test</a>
</li>
<li>
<a href="#homexv">test</a>
</li>
</ul>
</Nav>
);
});
이제 소품이 실제로 변경되지 않는 한 구성 요소가 다시 렌더링되지 않습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다