2016-11-03 4 views
0

Ich habe eine reaktive native App mit redux und unveränderlichen js. Wenn ich eine Aktion von meinem Hauptbildschirm aus aussende, geht sie durch meine Aktionen, zu meinem Reduzierer und dann zurück zu meinem Container. Die Ansicht wird jedoch nicht aktualisiert, und componentWillReceieveProps wird nie aufgerufen. Darüber hinaus ist der Hauptbildschirm eine Liste, deren Einträge Unterkomponenten Artikel sind. Hier ist der relevante Code für das Problem, wenn Sie mehr sehen möchten, lassen Sie es mich wissen.Wie Rendern Sub-Komponente auf Prop-Änderung mit Redux?

Render die Zeile mit den Daten:

renderRow(rowData) { 
    return (
     <Item item={ rowData } likePostEvent={this.props.likePostEvent} user={ this.props.user } removable={ this.props.connected } /> 
    ) 
} 

Der Teil Item.js derdiedas eine Aktion auslöst, und zeigt das Ergebnis:

<View style={{flex: 1, justifyContent:'center', alignItems: 'center'}}> 
         <TouchableOpacity onPress={ this.changeStatus.bind(this, "up") }> 
          <Image source={require('../img/up-arrow.png')} style={s.upDownArrow} /> 
         </TouchableOpacity> 
         <Text style={[s.cardText,{fontSize:16,padding:2}]}> 
          { this.props.item.starCount } 
         </Text> 
         <TouchableOpacity onPress={ this.changeStatus.bind(this, "down") }> 
          <Image source={require('../img/up-arrow.png')} style={[s.upDownArrow,{transform: [{rotate: '180deg'}]}]} /> 
         </TouchableOpacity> 
        </View> 

Die Aktion geht Feuerbasis versandt, welches Ein onChange-Handler, der eine andere Aktion auslöst.

Der Druckminderer:

const initialState = Map({ 
onlineList: [], 
offlineList: [], 
filteredItems: [], 
connectionChecked: false, 
user: '' 
}) 
... 
... 
case ITEM_CHANGED: 
list = state.get('onlineList') 
if(state.get('onlineList').filter((e) => e.id == action.item.id).length > 0){ 
    let index = state.get('onlineList').findIndex(item => item.id === action.item.id); 
    list[index] = action.item 
    list = list.sort((a, b) => b.time_posted - a.time_posted) 
} 
return state.set('onlineList', list) 
      .set('offlineList', list) 

Der Behälter:

function mapStateToProps(state) { 
return { 
    onlineItems: state.items.get('onlineList'), 
    offlineItems: state.items.get('offlineList'), 
    filteredItems: state.items.get('filteredItems'), 
    connectionChecked: state.items.get('connectionChecked'), 
    connected: state.items.get('connected'), 
    user: state.login.user 
    } 
} 

Wo ich die onChange verbinden:

export function getInitialState(closure_list) { 
    itemsRef.on('child_removed', (snapshot) => { 
    closure_list.removeItem(snapshot.val().id) 
    }) 
    itemsRef.on('child_added', (snapshot) => { 
    closure_list.addItem(snapshot.val()) 
    }) 

    itemsRef.on('child_changed', (snapshot) => { 
    closure_list.itemChanged(snapshot.val()) 
    }) 

    connectedRef.on('value', snap => { 
    if (snap.val() === true) { 
     closure_list.goOnline() 
    } else { 
     closure_list.goOffline() 
    } 
    }) 
    return { 
    type: GET_INITIAL_STATE, 
    connected: true 
    } 
} 

Anfangszustand Aufruf erhalten:

this.props.getInitialState({ 
     addItem: this.props.addItem, 
     removeItem: this.props.removeItem, 
     goOnline: this.props.goOnline, 
     goOffline: this.props.goOffline, 
     itemChanged: this.props.itemChanged 
    }) 

Alle Vorschläge sind willkommen, vielen Dank!

Antwort

0

Die Quelle Ihres Problems könnte mit dem Aufruf von Firebase sein. Wenn es sich um einen asynchronen Aufruf handelt, gibt der Returnbackback möglicherweise nicht etwas zurück, das von Ihrer Aktion verbraucht werden kann.

Wissen Sie, ob es ein Versprechen zurückgibt? Wenn dies der Fall ist, existiert eine Middleware, die solche Aufrufe behandelt und den Aufruf einer Aktion stoppt, bis eine korrekte Antwort empfangen wird. Eine solche Middleware ist Redux-Promise.

+0

Also ich bin mir nicht sicher, dass das das Problem ist, weil die zwei Aktionen getrennt sind. Wenn ich den Aufwärtspfeil drücke, wird eine Aktion gesendet, die die Datenbank ändert, separat, ich habe eine Funktion, die mit einem Änderungselement verbunden ist, das die Ansicht ändern soll. –

+0

Siehe aktualisierten Code oben –

0
import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { createStore,combineReducers } from 'redux' //Redux.createStore 
import { Provider,connect } from 'react-redux'; 



//Функція яка змінює store 
const hello = (state= {message:'none'}, action) => { 
    switch (action.type) { 
     case 'HELLO': 
      return Object.assign({}, state, {message:"hello world"}); 
      break 
     case 'buy': 
      return Object.assign({}, state, {message:"buy"}); 
      break; 
     case 'DELETE': 
      return Object.assign({}, state, {message:"none"}); 
      break; 
     default : 
      return state; 
    } 
}; 


const price = (state= {value:0}, action) => { 
    switch (action.type) { 
     case 'HELLO': 
      return Object.assign({}, state, {value: state.value + 1 }); 
      break; 
     default : 
      return Object.assign({}, state, {value:0}); 
    } 
}; 

const myApp = combineReducers({ 
    hello,price 
}); 

//створюємо store 
let store = createStore(myApp); 

let unsubscribe = store.subscribe(() => console.log(store.getState())) 



//VIEW 
class App extends React.Component { 

    constructor(props) { 
     super(props); 
    } 

    render() { 
     return (
      <div> 

       <p>value: {this.props.price}</p> 

       <a href="#" onClick={this.props.onClick}>click</a><b>{this.props.message}</b> 
      </div> 
     ) 
    } 
} 


//mapStateToProps() для чтения состояния и mapDispatchToProps() для передачи события 

const mapStateToProps = (state, ownProps) => { 
    return { 
     message: state.hello.message, 
     price: state.price.value 
    } 
}; 
const mapDispatchToProps = (dispatch, ownProps) => { 
    return { 
      onClick:() => { 

       var items= ['HELLO','buy','DELETE','error'] 
       var item = items[Math.floor(Math.random()*items.length)]; 

       dispatch({ type: item }) 
     } 
} 
} 


const ConnectedApp = connect(
    mapStateToProps, 
    mapDispatchToProps 
)(App); 




ReactDOM.render(
    <Provider store={store}> 
     <ConnectedApp /> 
    </Provider>, 
    document.getElementById('app') 
); 
Verwandte Themen