用户界面没有更新反应&终极版

时间:2016-03-04 07:14:03

标签: javascript reactjs react-native redux

我是react和redux的初学者,我有动作在API上发布JSON然后接收列表,这个动作从按钮点击调用,这个过程运行良好但是在填充数据之后ui没有更新

动作:

foreach (DataRow row in dt.Rows)
{
    Sale sales = new Sales();
    var date = Convert.ToDateTime(row["WeekStart"]);
    sale.WeekStart = date.ToString("MM/dd/yyyy"); // If sale.WeekStart field is string
}

减速机:

import * as types from './actionTypes'
import { postMessage } from '../api/messaging'

function postToAPI(msg, dispatch) {
  dispatch({ type: types.MESSAGE_POSTING });

  postMessage(msg, (messages) => {
    dispatch({
      type: types.MESSAGE_POST_DONE,
      messages: messages
    });
  });
}

export function postMessageAction(msg) {
  return (dispatch) => {
    postToAPI(msg, dispatch);
  }
}

主要容器:

import * as types from '../actions/actionTypes'

const initialState = {
  messages: []
}

export default function messages(state = initialState, action) {
  switch(action.type) {
    case types.MESSAGE_POST_DONE:
      return {
        ...state,
        messages: action.messages
      }
      this.forceUpdate();
    default:
      return state;
  }
}

CounterApp:

export default class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <CounterApp />
      </Provider>
    );
  }
}

信息:

class CounterApp extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    const { state, actions } = this.props;
    return (
      <Messaging />
    );
  }
}

export default connect(state => ({
  messages: state.default.messages.messages
}))(CounterApp);

消息列表:

class Messaging extends Component {
  render() {
    return (
      <View>
        <MessageList messages={this.props.messages} />
        <Message />
      </View>
    )
  }
}
export default connect(state => ({
  messages: state.default.messages.messages
}))(Messaging);

enter image description here

消息更改时,我的MessageList组件不会更新。我读了道具和州之间的区别,但我不知道如何将数据传递给州。

更新

我在消息传递连接中的状态看起来像我使用默认

的原因

enter image description here

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

你的代码看起来很奇怪。首先,您只需要在一个组件“Messaging”

中连接到redux
import { Component, PropTypes } from 'react';
import { connect } from 'react-redux';

const mapStateToProps = state => ({
  messages: state.messages.messages
});
@connect(mapStateToProps);

class Messaging extends Component {
  static propTypes = {
    messages: PropTypes.object
  }
  render() {
    const { messages } = this.props;
    return (
      <View>
        <MessageList messages={messages} />
        <Message />
      </View>
    )
  }
}

然后使用MessageList之类的dumb组件来接收和呈现数据。

  export default class MessageList extends Component {
    constructor(props) {
      super(props);
    }

    renderMessages(item, index) {
      return <Text>{item.body}</Text>;
    }

   render() {
     const { messages } =  this.props;

     return (
       <ScrollView>
        {messages.map((item, index) => this.renderMessages(item, index))}
      </ScrollView>
    );
  }
}

答案 1 :(得分:1)

我注意到的一些事情是:

  1. 从我所看到的状态中没有default对象(你写了messages: state.default.messages.messages)。
  2. 您不应在减速机中使用forceUpdate()
  3. 虽然它不会破坏任何内容,但CounterApp组件在不使用任何道具的情况下使用connect
  4. 请改为尝试:

    减速机:

    import * as types from '../actions/actionTypes'
    
    const initialState = {
      messages: []
    }
    
    export default function messages(state = initialState, action) {
      switch(action.type) {
        case types.MESSAGE_POST_DONE:
          return {
            ...state,
            messages: action.messages
          }
        default:
          return state;
      }
    }
    

    CounterApp:

    class CounterApp extends Component {
      render() {
        return (
          <Messaging />
        );
      }
    }
    

    信息:

    class Messaging extends Component {
      render() {
        return (
          <View>
            <MessageList messages={this.props.messages} />
            <Message />
          </View>
        )
      }
    }
    
    export default connect(state => ({
      messages: state.messages.messages
    }))(Messaging);
    

答案 2 :(得分:1)

我猜你的连接语句想要

messages: state.messages 

而不是

messages: state.default.messages.messages.

另外从我所看到的情况来看,我认为你不需要在CounterApp中使用连接语句,它没有做任何事情。

我不确定返回的邮件是应该替换还是与现有邮件合并,但您的reducer应该是

case types.MESSAGE_POST_DONE:
  return {
    messages: action.messages
  }

如果它替换现有列表或

case types.MESSAGE_POST_DONE:
  return {
    messages: [...state.messages, ...action.messages]
  }

如果你想合并它们。