簡體   English   中英

React App 僅在第一次狀態更改時重新渲染,即使更改成功,第二次更改也看不到更改

[英]React App only re-renders on first state change and changes are not visible for second change even though the change is successful

我正在嘗試在 React 應用程序中實現暗模式。 我在我的子組件上進行了切換,以將主題更改為暗模式。 因此,假設我們從暗模式開始並單擊切換,然后主題更改為亮模式。 現在,如果再次切換,主題不會改變,但狀態值會改變。

據我了解,如果一個狀態發生變化,組件應該重新渲染,而且它只會重新渲染一次!

請讓我知道出了什么問題。

App.js
------
import themes from '../theme';
import Container from '../common/container';

const App = function(props) {

 const [darkMode, setDarkMode] = React.useState(true);

 const changeTheme = function(){
  console.log('Dark Mode is ' + darkMode + ', Setting it to ' + !darkMode)
  setDarkMode(!darkMode)
 }
 
 return (
  <Router>
    <ThemeProvider theme={ darkMode ? themes.darkTheme : themes.lightTheme}>
      <CssBaseline />
      <Container darkMode={darkMode} changeTheme={changeTheme}>
        </Container>
    </ThemeProvider>
  </Router>
 );
}

如您所見,App 組件的狀態為 darkMode,並且其切換被傳遞給子組件 Container。

Container.js
------------

const Container = function(props) {
 return (
  <Box>
    <AppBar position="static">
        <Toolbar>
            .
            .
          <IconButton color="primary" onClick={(event) => props.changeTheme()}>{ props.darkMode ?
          <Brightness4Icon /> : <BrightnessHighIcon /> }</IconButton>

           <Button variant="contained" color="primary">Login</Button>
        </Toolbar>
    </AppBar>
    <Box>
      {props.children}
    </Box>
  </Box>
 )
}

所以在Container組件中,如果點擊IconButton,就會調用App組件的changeTheme函數。

現在,這段代碼的結果是 - 我只能在第一次點擊時更改主題,無論是先暗模式還是先亮模式。 第二次和進一步的點擊不會改變主題。

另外,正如您所注意到的,我在 changeTheme 中有一個日志語句。 PF 附加的控制台屏幕截圖。 在此處輸入圖片說明

因此,根據我的理解,如果 darkMode 更改,應用程序應該重新渲染。 但只是第一次做。

謝謝你的幫助!

我不確定您的代碼有什么問題,但是如果您使用的是Context ,則無需將 darkMode 傳遞給Container

我根據您的代碼制作了一個快速工作示例,對其進行修改以滿足您的需要。

import React from 'react'
import ReactDOM from 'react-dom'

const ThemeContext = React.createContext("light");

function App() {
  const [darkMode, setDarkMode] = React.useState(true);

  const changeTheme = function(){
    console.log('Dark Mode is ' + darkMode + ', Setting it to ' + !darkMode)
    setDarkMode(!darkMode)
 }  

  return (
    <ThemeContext.Provider value={darkMode ? "dark" : "light"}>
      <Container changeTheme={changeTheme}/>
    </ThemeContext.Provider>
  )
}

function Container({changeTheme}) {
  const theme = React.useContext(ThemeContext);

  return <React.Fragment>
    {theme}

    <button onClick={changeTheme}>Toggle Theme</button>
  </React.Fragment>;
}

ReactDOM.render(
  <App />,
  document.getElementById('container')
);

如您所見,在Container您可以使用useContext來獲取主題值,無需將其作為屬性傳遞,這就是上下文的全部意義所在。

您可以在此CodeSandbox 中測試上面的代碼

如果不清楚,您可以在React Docs 中閱讀有關useContext鈎子的更多信息。 還有一個主題上下文實現的例子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM