MapDispatchToProps nedir?


358

Redux kütüphanesinin belgelerini okuyordum ve bu örneği var:

Durumu okumaya ek olarak, kap bileşenleri eylemler gönderebilir. Benzer bir şekilde, sen adlı bir işlev tanımlayabilirsiniz mapDispatchToProps()aldığı dispatch()yöntem ve sunumsal bileşene enjekte etmek istedikleri döner sahne geri çağırma.

Bu aslında bir anlam ifade etmiyor. mapDispatchToPropsZaten sahip olduğunuzda neden ihtiyacınız var mapStateToProps?

Ayrıca bu kullanışlı kod örneğini sağlarlar:

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

Birisi layman'ın bu fonksiyonun ne olduğunu ve neden yararlı olduğunu açıklayabilir mi?

Yanıtlar:


578

Cevapların hiçbirinin neden mapDispatchToPropsfaydalı olduğunu kristalize etmediğini hissediyorum .

Bu gerçekten sadece container-componentilk okuma ile en iyi anlaşılan bulduğum kalıp bağlamında cevaplanabilir : Konteyner Bileşenleri sonra Reaksiyon ile Kullanım .

Özetle, componentssadece bir şeyler sergilemekle ilgilenmeniz gerekiyor. Bilgi almaları gereken tek yer sahne .

"Sergileme materyallerinden" (bileşenler) ayrıdır:

  • şeyleri nasıl görüntüleyeceğinizi,
  • ve olayları nasıl ele aldığınızı.

Bunun containersiçin.

Bu nedenle, componentdesende "iyi tasarlanmış" şöyle görünür:

class FancyAlerter extends Component {
    sendAlert = () => {
        this.props.sendTheAlert()
    }

    render() {
        <div>
          <h1>Today's Fancy Alert is {this.props.fancyInfo}</h1>
          <Button onClick={sendAlert}/>
        </div>
     }
}

Bu bileşenin görüntülediği bilgileri sahne alanından (redux mağazasından gelen mapStateToProps) nasıl aldığını ve ayrıca eylem işlevini sahne alanlarından nasıl aldığını görün sendTheAlert().

İşte bu noktada mapDispatchToPropsdevreye giriyor:container

// FancyButtonContainer.js

function mapDispatchToProps(dispatch) {
    return({
        sendTheAlert: () => {dispatch(ALERT_ACTION)}
    })
}

function mapStateToProps(state) {
    return({fancyInfo: "Fancy this:" + state.currentFunnyString})
}

export const FancyButtonContainer = connect(
    mapStateToProps, mapDispatchToProps)(
    FancyAlerter
)

Acaba görebilirsiniz, şimdi redux ve sevk ve depolamak ve devlet ve ... şeyler bilen container 1 olduğunu.

componentDesende, FancyAlerter, render da herhangi bir madde hakkında bilmek gerekmez yok ki: en çağrısına onun yöntemini alır onClickonun sahne aracılığıyla, düğmeye.

Ve ... mapDispatchToPropsredux'un, konteynerin bu işlevi destekleri üzerindeki sarılı bileşene kolayca geçirmesine izin vermesinin sağladığı kullanışlı araçtı.

Bütün bunlar dokümanlardaki todo örneğine çok benziyor ve burada başka bir cevap var, ama nedenini vurgulamak için onu desen ışığında kullanmaya çalıştım .

(Not: içeriye erişiminizin olmadığı temel nedenden dolayı mapStateToPropsaynı amaçla kullanamazsınız . Bu nedenle , sarılmış bileşene kullanılan bir yöntemi vermek için kullanamazsınız . mapDispatchToPropsdispatchmapStateToPropmapStateToPropsdispatch

Neden iki haritalama işlevi içine kırmak için seçtik bilmiyorum - mapToProps(state, dispatch, props) her ikisini de IE bir işlevi olması daha düzenli olabilir !


1 Kabı kasten açık bir şekilde adlandırdığımı, FancyButtonContainerbunun bir "şey" olduğunu vurgulamak için kullandığımı - kabın "bir şey" olarak kimliğinin (ve dolayısıyla varlığının!) Bazen stenoda kaybolduğunu unutmayın.

export default connect(...) ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

çoğu örnekte gösterilen sözdizimi


5
Hala bilmek istiyorum: Bir bileşen içinden store.dispatch doğrudan arayarak gerekli işlevsellik hakkında ne?
pixelpax

8
@ user2130130 Yok. İyi tasarım hakkında. Bileşeninizi store.dispatch ile eşleştirdiyseniz, redux'u dışarıda bırakmaya karar verdiğinizde veya redxu tabanlı olmayan (veya şimdi düşünemediğim başka bir şey) bir yerde kullanmak istediğinizde, birçok değişiklik. Sorunuz "neden 'iyi tasarım uygulamaları' ile uğraşıyoruz? mapDispatchToProps, iyi tasarlanmış, temiz bir şekilde ayrılmış bileşenler yazabilmeniz için sağlanmıştır.
GreenAsJade

4
Gerçekten burada alamadım nedir: ALERT_ACTIONeylem işlevi veya eylem işlevinden typedöndürülen mi? : / çok şaşkın
Jamie Hutber

1
@JamieHutber Kesinlikle, ALERT_ACTION'ın bu soru ile ilgisi yok. Göndermek için geçerli bir argüman ve olduğu gibi, kodumda , redux.js.org/docs/api/Store.html#dispatch açıklandığı gibi, dağıtımı kullanan bir nesneyi döndüren bir "eylem oluşturucu" dan geliyor . Buradaki ana nokta, sevkıyatın nasıl çağrılacağının kapta açıklanması ve bileşen desteklerine aktarılmasıdır. Bileşen, işlevlerini yalnızca sahne alanlarından alır, başka hiçbir yerde. Bu modelde bunu yapmanın "yanlış" yolu, bileşene gönderimi iletmek ve bileşende aynı çağrıyı yapmak olacaktır.
GreenAsJade

1
Alt bileşene sahne olarak geçirilmesi gereken birden fazla eylem oluşturucunuz varsa, alternatifleri bunları mapDispatchToProps içindeki bindActionCreators ile sarmaktır (bkz. Redux.js.org/docs/api/bindActionCreators.html ); başka bir alternatif, connect (), örneğin connect (mapStateToProps, {actioncreators}) için bir eylem yaratıcıları nesnesi sağlamaktır, tepki-redux onları sizin için dispatch () ile sarar.
dave

81

Temelde bir steno. Yani yazmak yerine:

this.props.dispatch(toggleTodo(id));

MapDispatchToProps'ı örnek kodunuzda gösterildiği gibi kullanır ve başka bir yere şunu yazarsınız:

this.props.onTodoClick(id);

veya daha büyük olasılıkla bu durumda, olay işleyicisi olarak buna sahip olursunuz:

<MyComponent onClick={this.props.onTodoClick} />

Dan Abramov'un bu konuda yararlı bir videosu var: https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-visibletodolist


Teşekkür ederim. Ben de merak ediyorum, ilk etapta sevk sahne nasıl eklenir?
Code Whisperer

14
Kendi mapDispatchişlevinizi sağlamazsanız , Redux bir varsayılan kullanır. Bu varsayılan mapDispatchişlev, dispatchişlev başvurusunu alır ve size şu şekilde verir this.props.dispatch.
markerikson

7
Gönderme yöntemi, Sağlayıcı Bileşeni
Diego Haz

55

mapStateToProps()bileşeninizin güncellenmiş duruma (diğer bazı bileşenler tarafından güncellenir)
mapDispatchToProps()yardımcı olan bir yardımcı programdır, bileşeninizin bir eylem olayı başlatmasına yardımcı olacak bir yardımcı programdır (uygulama durumunun değişmesine neden olabilecek eylem gönderme)


23

mapStateToProps, mapDispatchToPropsVe connectgelen react-reduxkütüphaneye sizin erişmek için uygun bir yol sağlar stateve dispatchmağaza fonksiyonunu. Temel olarak connect daha yüksek bir sipariş bileşenidir, bu sizin için anlamlıysa bir sarıcı olarak da düşünebilirsiniz. Böylece her statedeğişiklik yaptığınızda mapStateToPropsyeni ile çağrılır stateve daha sonra propsbileşeni güncelledikçe, bileşeninizi tarayıcıda oluşturmak için oluşturma işlevi çalışır. mapDispatchToPropsAyrıca anahtar / değer çiftlerini propsbileşeninizin üzerinde depolar , genellikle bir işlev biçimini alırlar. Böyle yolla tetikleyebileceğiniz statebileşeninizden değişikliği onClick, onChangeolayları.

Dokümanlar'dan:

const TodoListComponent = ({ todos, onTodoClick }) => (
  <ul>
    {todos.map(todo =>
      <Todo
        key={todo.id}
        {...todo}
        onClick={() => onTodoClick(todo.id)}
      />
    )}
  </ul>
)

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

function toggleTodo(index) {
  return { type: TOGGLE_TODO, index }
}

const TodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList) 

Ayrıca React durum bilgisi olmayan işlevleri ve Yüksek Dereceli Bileşenleri bildiğinizden emin olun


Yani sevk temelde olay gibidir?
Code Whisperer

2
Olayla ilgili olabilir, gönderme sadece bir işlevdir ve uygulama durumunuzu değiştirmenin tek yoludur . mapStateToProps , mağazanızın gönderme işlevini React Component'a göstermenin bir yoludur . Ayrıca connect'in redux'un bir parçası olmadığını, reat ve redux ile çalışmak için reakt-redux adlı bir yardımcı program ve kazan plakası azaltma kütüphanesi olduğunu unutmayın . Mağazanızı kök reaksiyon bileşeninden çocuklara geçirirseniz , aynı sonucu tepki redux olmadan da elde edebilirsiniz .
Vlad Filimon

3

mapStateToPropsalır stateve propsbileşene geçmek için devletten sahne çıkarmanızı sağlar.

mapDispatchToPropsalır dispatchve propsve eylem sevk alır çıkan işlevini yürütmek zaman bu kadar göndermeye bağlamak eylem yaratıcıları için size içindir.

Bunun sadece dispatch(actionCreator())bileşeninizde yapmak zorunda kalmamanızı sağladığını ve böylece okumayı biraz daha kolay hale getirdiğini düşünüyorum.

https://github.com/reactjs/react-redux/blob/master/docs/api.md#arguments


Teşekkür ederim ama dispatchyöntemin değeri nedir? Nereden geliyor?
Code Whisperer

ah. Sevk etmek temel olarak eylemin redux / flux tek yönlü akışını başlatmasını sağlar. Diğer cevaplar sorunuzu bundan daha iyi yanıtlamış gibi görünüyor.
Harry Moreno

Ayrıca, sevk yöntemi, <Provider/>kendisi tarafından sağlanan geliştirmeden gelir . Sevkinin çocuk bileşenlerinde mevcut olmasını garanti etmek için kendi yüksek dereceli bileşen büyüsünü yapar.
Ricardo Magalhães

3

Şimdi redux için bir eylem olduğunu varsayalım:

export function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

İçe aktardığınızda,

import {addTodo} from './actions';

class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.onTodoClick(); // This prop acts as key to callback prop for mapDispatchToProps
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

const mapDispatchToProps = dispatch => {
    return {
      onTodoClick: () => { // handles onTodoClick prop's call here
        dispatch(addTodo())
      }
    }
}

export default connect(
    null,
    mapDispatchToProps
)(Greeting);

İşlev adından da anlaşılacağı gibi mapDispatchToProps(), dispatchişlemi propslarla eşleştirin (bileşenimizin sahne donanımı)

Bu yüzden prop onTodoClick, mapDispatchToPropseylemi göndermeden önce delegelere giden bir işlev anahtarıdır addTodo.

Ayrıca kodu kırpmak ve manuel uygulamayı atlamak istiyorsanız, bunu yapabilirsiniz,

import {addTodo} from './actions';
class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.addTodo();
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

export default connect(
    null,
    {addTodo}
)(Greeting);

Bu tam anlamıyla

const mapDispatchToProps = dispatch => {
    return {
      addTodo: () => { 
        dispatch(addTodo())
      }
    }
}
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.