2016-11-03 4 views
0

У меня есть ответное приложение с использованием сокращений и неизменяемых js. Когда я отправляю действие с моего главного экрана, он проходит через мои действия, мой редуктор, а затем обратно в мой контейнер, однако представление не обновляется, а компонентWillReceieveProps никогда не вызывается. Кроме того, основным экраном является список, элементы которого являются подкомпонентами Позиция. Вот соответствующий код для проблемы, если вы хотите, чтобы узнать больше, дайте мне знать.Как переопределить подкомпонент на смену с помощью редукса?

Отрендерьте строку с данными:

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

Часть Item.js, которая отправляет действие, и показывает результат:

<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> 

Действие посланы идет к firebase, который имеет обработчик onChange, который отправляет другое действие.

Редуктор:

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) 

Контейнер:

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 
    } 
} 

Где подключить OnChange:

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 
    } 
} 

Вызов получить начальное состояние:

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

Любые предложения приветствуются, спасибо огромное!

ответ

0

Источником вашей проблемы может быть звонок в Firebase. Если это асинхронный вызов, обратный вызов возврата может не возвращать то, что может быть использовано вашим действием.

Знаете ли вы, что он возвращает обещание? Если это так, существует промежуточное ПО, которое обрабатывает такие вызовы и останавливает вызов действия до получения правильного ответа. Одним из таких промежуточных программ является Redux-Promise.

+0

Так что я не уверен, что проблема связана с тем, что эти два действия являются отдельными. Когда я нажимаю стрелку вверх, он отправляет действие, которое меняет базу данных, отдельно, у меня есть функция, связанная с элементом изменения, который должен изменить вид. –

+0

См. Обновленный код выше –

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') 
); 

 Смежные вопросы

  • Нет связанных вопросов^_^