Reactjs 连接的react redux组件不会在状态时重新加载

Reactjs 连接的react redux组件不会在状态时重新加载,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我正在尝试编写一个简单的TestReact redux应用程序来开始使用gmail API,而现在状态更改并没有强制重新渲染 我所做的: 我读书。此人的问题似乎是由于未连接组件造成的,但据我所知,我正在这样做。我读书。那个人的问题是由于误解了combinereducer如何在状态上设置对象造成的,但我认为我没有同样的误解。我肯定还有别的 这是我的顶级容器,包含路由: 'use strict' import React from 'react' import {Router, Route, Ind

我正在尝试编写一个简单的TestReact redux应用程序来开始使用gmail API,而现在状态更改并没有强制重新渲染

我所做的

我读书。此人的问题似乎是由于未连接组件造成的,但据我所知,我正在这样做。我读书。那个人的问题是由于误解了
combinereducer
如何在状态上设置对象造成的,但我认为我没有同样的误解。我肯定还有别的

这是我的顶级容器,包含路由:

'use strict'
import React from 'react'
import {Router, Route, IndexRedirect, browserHistory} from 'react-router'
import {render} from 'react-dom'
import {connect, Provider} from 'react-redux'

import store from './store'
import Home from './components/Home'
import Login from './components/Login'
import WhoAmI from './components/WhoAmI'
import NotFound from './components/NotFound'
import { handleClientLoad } from './gmailApi'

const ExampleApp = connect(
  ({ auth }) => ({ user: auth })
)(
  ({ user, children }) =>
    <div>
      <nav>
        {user ? <WhoAmI/> : <Login/>}
      </nav>
      {children}
    </div>
)

const onAppEnter = () => {
  handleClientLoad()
}

render(
  <Provider store={store}>
    <Router history={browserHistory}>
      <Route path="/" component={ExampleApp}>
        <IndexRedirect to="/home" />
        <Route path="/home" component={Home} onEnter={onAppEnter} />
      </Route>
      <Route path='*' component={NotFound} />
    </Router>
  </Provider>,
  document.getElementById('main')
)
这里是我组合减速器的地方:

import { combineReducers } from 'redux'

const rootReducer = combineReducers({
  auth: require('./auth').default, 
  gmail: require('./gmail').default
})
export default rootReducer
这是显示我的控制台的屏幕截图。(我真的不理解这个跨帧原点错误,希望得到解释,但我认为这是我的问题的辅助原因,因为我克服了它并成功地通过了减速器传递了操作。)

我成功地在第一次呈现时控制台记录标签,但在状态上设置标签后,没有重新呈现器,并且我不会再次控制台记录标签(或呈现页面上的标签列表)

谢谢你能提供的任何帮助

p、 为了完整起见,这里是我做异步gmail api的地方。(我知道我现在没有遵循异步操作创建者的格式。我正在使用gmail api中的示例代码,只是尝试先启动并运行一些东西,然后扩展和清理我的代码。我认为问题不可能出现在这里,因为状态填充得很好;我只是无法重新渲染页面。)

从“../store”导入存储
从“../reducers/gmail”导入{signedIn,receiveLabels}
从“/gapi”导入gapi
导入“../store”

var CLIENT_ID='我看到的一个错误是您没有导出连接的组件。导出零部件,然后稍后再连接。connect函数返回一个新的高阶组件;它不会影响组件本身。此外,connect函数还有第二个参数:将动作分派到状态存储的动作创建者。如果你想让这些动作发射到你的减速器上,你需要导入它们

你有:

export default class Home extends Component {

  constructor(props) {
    super(props)

    this.state = {labels: [], isSignedIn: false}
  }

  render() {
    return (
        <Labels labels={this.props.labels} isSignedIn={this.props.isSignedIn}/>
    )
  }

}

connect(mapStateToProps)(Home)
导出默认类主扩展组件{
建造师(道具){
超级(道具)
this.state={labels:[],isSignedIn:false}
}
render(){
返回(
)
}
}
连接(mapStateToProps)(主页)
只需将其更改为:

import * as actions from './nameOfActionsFolder';

class Home extends Component {

  constructor(props) {
    super(props)

    this.state = {labels: [], isSignedIn: false}
  }

  render() {
    return (
        <Labels labels={this.props.labels} isSignedIn={this.props.isSignedIn}/>
    )
  }

}

export default connect(mapStateToProps, actions)(Home);
import*作为来自“/nameofcationsfolder”的操作;
类Home扩展组件{
建造师(道具){
超级(道具)
this.state={labels:[],isSignedIn:false}
}
render(){
返回(
)
}
}
导出默认连接(MapStateTops,actions)(主);

这样,您将导出连接的组件。

我相信您是对的,我还没有投票接受您的答案的唯一原因是,由于某种原因,现在与gmail api的连接不起作用,并且我没有更新状态的标签,因此我无法验证您的建议是否修复了任何问题。我试图找出哪里出了问题,以及更新我的问题或提出新问题是否合适。是的,我不知道api是如何工作的。此外,如果使用redux,则不需要本地状态。也许解决问题的一个好方法是摆脱redux,并尝试使其与react组件中的本地状态一起工作,然后将功能分解到redux中。我修复了它。我只需要将fetchLabels()作为.sign()调用,然后关闭.sign()。我认为之前没有造成问题的唯一原因是我的登录状态一直存在于浏览器中,因此始终有一个用户可供fetchLabels查找。我接受你的回答。谢谢你的帮助!
import store from '../store'
import { signedIn, receiveLabels } from '../reducers/gmail'
import gapi from './gapi'
import '../store'

var CLIENT_ID = '<stack overflow doesn't need to know this>';

// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"];

// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = "https://www.googleapis.com/auth/gmail.modify";


/**
 *  On load, called to load the auth2 library and API client library.
 */


export const handleClientLoad = function() {
    gapi.load('client:auth2', initClient);
}

/**
 *  Initializes the API client library and sets up sign-in state
 *  listeners.
 */
function initClient() {
    gapi.client.init({
        discoveryDocs: DISCOVERY_DOCS,
        clientId: CLIENT_ID,
        scope: SCOPES
    }).then(function () {
        // Listen for sign-in state changes.
        gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus)

        // Handle the initial sign-in state.
        updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());


    });
}

function updateSigninStatus(isSignedIn) {

        console.log(isSignedIn)
        store.dispatch(signedIn(isSignedIn))
}

/**
 *  Sign in the user upon button click.
 */
export const handleAuthClick = function(event) {
    console.log("got here")
    gapi.auth2.getAuthInstance().signIn();
    fetchLabels()
}

/**
 *  Sign out the user upon button click.
 */
export const handleSignoutClick = function(event) {
    gapi.auth2.getAuthInstance().signOut();
}

/**
 * Append a pre element to the body containing the given message
 * as its text node. Used to display the results of the API call.
 *
 * @param {string} message Text to be placed in pre element.
 */

/**
 * Print all Labels in the authorized user's inbox. If no labels
 * are found an appropriate message is printed.
 */
function fetchLabels() {
    console.log("gapi client ", gapi.client)
    gapi.client.gmail.users.labels.list({
        'userId': 'me'
    }).then(function (response) {
        var labels = response.result.labels;
        store.dispatch(receiveLabels(labels))
    })
}
export default class Home extends Component {

  constructor(props) {
    super(props)

    this.state = {labels: [], isSignedIn: false}
  }

  render() {
    return (
        <Labels labels={this.props.labels} isSignedIn={this.props.isSignedIn}/>
    )
  }

}

connect(mapStateToProps)(Home)
import * as actions from './nameOfActionsFolder';

class Home extends Component {

  constructor(props) {
    super(props)

    this.state = {labels: [], isSignedIn: false}
  }

  render() {
    return (
        <Labels labels={this.props.labels} isSignedIn={this.props.isSignedIn}/>
    )
  }

}

export default connect(mapStateToProps, actions)(Home);