Connect w / Redux kullanarak this.props'tan basit gönderim nasıl elde edilir?


107

Bağladığım basit bir React bileşenim var (üzerinden basit bir dizi / durum eşleme). Mağazanın içeriğine referans vermekten kaçınmak için, doğrudan sahne donanımlarından "gönderim" almanın bir yolunu istiyorum. Başkalarının bu yaklaşımı kullandığını gördüm, ancak nedense buna erişimim yok :)

Şu anda kullandığım her npm bağımlılığının sürümleri burada

"react": "0.14.3",
"react-redux": "^4.0.0",
"react-router": "1.0.1",
"redux": "^3.0.4",
"redux-thunk": "^1.0.2"

İşte bağlantı yöntemi ile bileşen

class Users extends React.Component {
    render() {
        const { people } = this.props;
        return (
            <div>
                <div>{this.props.children}</div>
                <button onClick={() => { this.props.dispatch({type: ActionTypes.ADD_USER, id: 4}); }}>Add User</button>
            </div>
        );
    }
};

function mapStateToProps(state) {
    return { people: state.people };
}

export default connect(mapStateToProps, {
    fetchUsers
})(Users);

Redüktörü görmeniz gerekiyorsa (heyecan verici bir şey değil ama işte burada)

const initialState = {
    people: []
};

export default function(state=initialState, action) {
    if (action.type === ActionTypes.ADD_USER) {
        let newPeople = state.people.concat([{id: action.id, name: 'wat'}]);
        return {people: newPeople};
    }
    return state;
};

Yönlendiricimin redux ile nasıl yapılandırıldığını görmeniz gerekiyorsa

const createStoreWithMiddleware = applyMiddleware(
      thunk
)(createStore);

const store = createStoreWithMiddleware(reducers);

var Route = (
  <Provider store={store}>
    <Router history={createBrowserHistory()}>
      {Routes}
    </Router>
  </Provider>
);

Güncelleme

Görünüşe göre eğer bağlantıda kendi gönderimi atlarsam (şu anda yukarıda fetchUsers'ı gösteriyorum), gönderimi ücretsiz alacağım (sadece eşzamansız eylemler içeren bir kurulumun genellikle böyle çalışıp çalışmayacağından emin değilim). İnsanlar karışıyor mu yoksa hepsi mi yoksa hiç mi?

[mapDispatchToProps]

Yanıtlar:


280

Varsayılan mapDispatchToPropsolarak sadece dispatch => ({ dispatch }).
İkinci değişkeni için belirttiğiniz yoksa Yani connect(), sen alırsınız dispatchsizin bileşeninde figüran olarak enjekte edildi.

'E özel bir işlev mapDispatchToPropsiletirseniz, işlevle her şeyi yapabilirsiniz.
Birkaç örnek:

// inject onClick
function mapDispatchToProps(dispatch) {
  return {
    onClick: () => dispatch(increment())
  };
}

// inject onClick *and* dispatch
function mapDispatchToProps(dispatch) {
  return {
    dispatch,
    onClick: () => dispatch(increment())
  };
}

Redux size biraz yazmaktan tasarruf etmek için bunu bindActionCreators()çevirmenize izin verir:

// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch) {
  return {
    onPlusClick: () => dispatch(increment()),
    onMinusClick: () => dispatch(decrement())
  };
}

bunun içine:

import { bindActionCreators } from 'redux';

// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    onPlusClick: increment,
    onMinusClick: decrement
  }, dispatch);
}

hatta prop isimleri aksiyon yaratıcısı isimleriyle eşleştiğinde daha da kısadır:

// injects increment and decrement
function mapDispatchToProps(dispatch) {
  return bindActionCreators({ increment, decrement }, dispatch);
}

İsterseniz dispatchoraya kesinlikle elle ekleyebilirsiniz :

// injects increment, decrement, and dispatch itself
function mapDispatchToProps(dispatch) {
  return {
    ...bindActionCreators({ increment, decrement }), // es7 spread syntax
    dispatch
  };
}

Bunu yapıp yapmamanız konusunda resmi bir tavsiye yok. connect()genellikle Redux-farkında olan ve Redux-farkında olmayan bileşenler arasında sınır görevi görür. Bu nedenle, genellikle hem bağlı eylem yaratıcılarını hem dedispatch . Ancak bunu yapmanız gerektiğini düşünüyorsanız, çekinmeyin.

Son olarak, şu anda kullandığınız model, aramadan bile daha kısa bir kısayol bindActionCreators. Tek yapmanız gereken geri dönmek olduğunda bindActionCreators, bunu yapmak yerine aramayı atlayabilirsiniz:

// injects increment and decrement
function mapDispatchToProps(dispatch) {
  return bindActionCreators({ increment, decrement }, dispatch);
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App);

bu şekilde yazılabilir

export default connect(
  mapStateToProps,
  { increment, decrement } // injects increment and decrement
)(App);

Ancak, geçmek dispatchgibi daha özel bir şey istediğinizde, bu güzel kısa sözdiziminden vazgeçmeniz gerekecek .


2
@DanAbramov btw bindActionCreators(actionCreators, dispatch)isteğe bağlı ikinci parametredir ? Ben de Kodunuzdaki fark // es7 spread syntaxhattı, dispatchverili değildirbindActionCreators
yonasstephen

iç artış yöntemi nedir?
Khurshid Ansari

es7 yayılma sözdizimi şöyle olmalıdırfunction mapDispatchToProps(dispatch) { return { ...bindActionCreators({ increment, decrement }), dispatch }; }
Siyah

6

Genellikle ne istediğinize göre karıştırıp eşleştirebilirsiniz.

Sen edebilirsiniz geçmesi dispatcheğer istediğin buysa figüran olarak tarih:

export default connect(mapStateToProps, (dispatch) => ({
    ...bindActionCreators({fetchUsers}, dispatch), dispatch
}))(Users);

Nasıl emin değilim fetchUserskullanılır (bir zaman uyumsuz fonksiyonu olarak?), Ancak genellikle böyle bir şey kullanmak bindActionCreatorsiçin otomatik bağlamak kullanma hakkında endişe gönderilecek ve ardından olmazdı dispatchbağlı unsurda doğrudan.

dispatchDizin kullanmak aptal , durumsuz bileşeni redux ile eşleştirir. Bu onu daha az taşınabilir hale getirebilir.


3
Önerdiğin şey işe yaramayacak. fetchUsersBir destek olarak bağlanmamış enjekte edilirsiniz. Kısayol gösterimi yalnızca bir nesneyi ikinci argüman olarak ilettiğinizde çalışır. Eğer bir işlev geçmesi zaman aramak zorunda bindActionCreatorskendinizi: dispatch => ({ ...bindActionCreators({ fetchUsers }, dispatch), dispatch }).
Dan Abramov

Neden doğrudan bindActionCreators'da dağıtılmalı ve gönderilmeli? dispatch => ( bindActionCreators({ dispatch, fetchUsers }, dispatch))
user3711421

2

Bir dispatchparçası olarak aşağı inebilirsiniz dispatchToProps, ancak bileşenlerinize storeveya dispatchdoğrudan bileşenlerinizin içinden erişmekten kaçınmanızı öneririm . Görünüşe göre, connect'in 2. argümanına bağlı bir eylem oluşturucuyu geçerek daha iyi hizmet edeceksinizdispatchToProps

Burada yayınladığım bir örneğe bakın: https://stackoverflow.com/a/34455431/2644281 "zaten bağlı bir eylem oluşturucunun" bu şekilde nasıl aktarılacağına dair bileşenlerinizin doğrudan mağaza / sevkıyat hakkında bilgi sahibi olması veya ona bağlı olması gerekmez .

Kısaca özür dilerim. Daha fazla bilgi ile güncelleyeceğim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.