我有此代码:
$str = '<p>2:45 text goes here</p>
<p>43:41 - text goes here</p>';
$str = preg_replace('/<p>(\d+:\d+ ((?!<\/p>).)+)<\/p>/','<li>$1</li>',$str);
echo $str;
和
import React, { Component } from 'react';
import { connect } from 'react-redux'; //this is a single connect property
import { selectBook } from '../actions/index';
import { bindActionCreators } from 'redux';
class BookList extends Component {
renderList() {
return this.props.books.map(book => {
return (
<li key={book.title} className="list-group-item"> {book.title} </li>
);
});
}
render() {
return (
<ul className="list-group col-sm-4">
{this.renderList()}
</ul>
)
}
}
function mapStateToProps(state) {
return {
books: state.books
}
}
function mapDispatchToProps(dispatch) {
// Whenver selectBook is called, the result should be passed to all of the reducers.
// selectBook value is an actionCreator, a function.
return bindActionCreators({ selectBook: selectBook }, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(BookList)
我不理解的部分是这样:
export function selectBook(book) {
console.log("A book has been seelcted:", book.title)
}
这是怎么回事?这部分负责将状态和调度方法提供给组件connect(mapStateToProps, mapDispatchToProps)(BookList)
吗?
此函数在做什么:
BookList
这些内置的redux函数吗?他们还回来什么?到底是怎么回事?什么是function mapDispatchToProps(dispatch) {
// Whenver selectBook is called, the result should be passed to all of the reducers.
// selectBook value is an actionCreator, a function.
return bindActionCreators({ selectBook: selectBook }, dispatch)
}
?
右边的值dispatch
是函数对吗?所以我猜想它会被调用,并且返回值将通过调度方法流经reducers?但是selectBook
在做什么呢?
如何在组件bindActionCreators
中提供道具?
答案 0 :(得分:3)
您有太多问题,我们尝试解释这一问题的努力可能会使您更加困惑。我强烈建议您观看Redux创作者的这两段视频:
Getting started with Redux 和 Idiomatic Redux
那些视频解释了什么是Redux,它的各个部分如何融合在一起。因此,在进行任何其他教程之前,请先掌握Redux本身。
此外,Redux的official documentation很棒,如果您将其与视频一起观看,将对您的学习很有帮助。
但是,无论如何,让我回答您的问题。
第一个问题
我不理解的部分是这样:
connect(mapStateToProps, mapDispatchToProps)(BookList)
这是怎么回事?这部分负责建立国家和 组件BookList可用的调度方法?
答案
connect
是react-redux
包提供的,而不是redux
本身提供的。它是一个辅助的高阶函数,用于向您的组件打开状态和动作创建者。所以,你猜对了。人们通常是通过这种方式将其组件连接到商店以获取状态和调度(以使用动作创建者)。
第二个问题
function mapDispatchToProps(dispatch) {
// Whenver selectBook is called, the result should be passed to all of the reducers.
// selectBook value is an actionCreator, a function.
return bindActionCreators({ selectBook: selectBook }, dispatch)
}
这些内置的redux函数吗?他们还回来什么?什么是 继续吗什么是调度?
右边的selectBook值是函数吧?所以我猜 它被调用,返回值将流经reducers 通过调度方法?但是,bindActionCreators在做什么呢?
如何在组件BookList中提供道具?
答案
不,正如我在第一个答案中所解释的那样,它们不是Redux函数内置的。 mapStateToProps
将您的状态打开到组件中,并将其作为道具提供。因此,如果您使用connect
和mapStateToProps
打开组件的任何状态,则此状态将作为props。在您的示例中,您从全局状态中获得了books
状态,并以books
的形式打开了您的组件。然后,此组件将其作为this.props.books
。
mapDispatchToProps
将您的动作创建者功能作为道具打开。有两种使用方法,bindActionCreators
是其中一种,但实际上您在这里不需要它。如果在调度动作创建者或将动作创建者传递给不了解Redux的子组件时需要它,则对于获得状态非常有用。因此,bindActionCreators
并不是了解mapDispatchToProps
的一个好的开始。
基本上就是这样:
const mapDispatchToProps = dispatch => ({
someFunction: () => dispatch(someFunction())
})
在这里,您将someFunction()
动作创建者以someFunction
的名称打开到组件中。您可以使用其他名称,也可以在此处使用其他人员,然后根据此dispatch
来创建动作创建者。但是在此示例中,您没有做任何额外的事情,只是调度了动作创建者。因此,这是一个简写:
const mapDispatchToProps = {
someFunction,
}
是的,在这种情况下,它做同样的事情。甚至更短一些:
connect(mapStateToProps, {someFunction})(Component)
无需使用mapDispatchToProps
,就可以像这样使用动作创建者,然后将其作为道具。
此外(是的,还有更多:))事件,而无需在connect中使用任何函数参数,我们可以使用动作创建器。
connect()(Component)
connect(mapStateToProps)(Component)
如果像上述方法之一一样跳过mapDispatchToProps
,则dispatch
将自动传递给组件props。然后,我们可以像使用其他任何道具一样使用它来分发我们的动作创建者:
this.props.dispatch(someFunction())
对于您的示例,它是这样的(我知道这个应用程序,所以我在这里使用真实动作创建者示例)。
您可以这样写mapDispatchToProps
:
const mapDispatchToProps = dispatch => ( {
selectBook: book => dispatch( selectBook( book ) ),
} );
在这里,您将selectBook
用作组件中的this.props.selectBook
并调度操作。您会看到您的道具实际上触发了一个函数,并在此处调度了您的实际动作创建者。请记住,动作创建者返回对象,并且需要分派这些对象才能通过化简器。因此,您正在分派动作创建者(由selectBook
返回。
现在,bindActionCreators
可以利用它的真正优势,将其编写为:
const mapDispatchToProps = dispatch => (
bindActionCreators( { selectBook: selectBook }, dispatch )
);
或某些具有相同名称的对象键的ES6速记:
const mapDispatchToProps = dispatch => (
bindActionCreators( { selectBook }, dispatch )
);
这比第一个短。您无需指向函数并分派它。您将动作创建者交给了bindActionCreators
,它就为您完成了工作。
现在,距离较短的那是因为您刚刚调度:
const mapDispatchToProps = {
selectBook,
};
即使没有mapDispatchToProps
:
connect( mapStateToProps, { selectBook } )( BookList )
因此,Provider
提供了connect
,react-redux
,使我们的生活更轻松。 mapStateToProps
和mapDispatchToProps
是connect
等待的功能。名称并不重要,我们可以为它们使用任何名称,但这是每个人都使用的事实上的名称。该顺序很重要,如果要跳过mapStateToProps
,必须在其位置使用null
,例如:
connect( null, mapDispatchToProps )( Component )
实际上,没有connect
,我们可以通过两种方式使用store
及其包含的内容getState
,dispatch
,subscribe
,包括两种方式:
react-redux
并将store
作为道具一直传递到要使用的每个组件。然后通过this.props.store
到达它。react-redux
的{{1}},然后对组件使用Provider
以获取context
。您可以想象,将商店一直传递到各个组件是一场噩梦。
首先将store
与store
一起使用,您需要指定组件的context
:
contextTypes
这样做之后,您可以从BookList.contextTypes = {
store: React.PropTypes.object.isRequired
};
获取存储,并使用this.context.store
来获取状态,或者使用getState
来分发动作创建者。
如果不使用dispatch
,我们的组件将是这样:
connect
这里我们使用:import React, { Component } from "react";
import { selectBook } from "../actions/index";
class BookList extends Component {
renderList() {
return this.context.store.getState().books.map( book =>
( <li
key={book.title}
onClick={() => this.context.store.dispatch( selectBook( book ))}
>
{book.title}
</li> ) );
}
render() {
return (
<ul>
{this.renderList()}
</ul>
);
}
}
BookList.contextTypes = {
store: React.PropTypes.object.isRequired,
};
export default BookList;
代替this.context.store.getState().books
,this.props.books
代替this.context.store.dispatch( selectBook( book ))
。如您所见,我们可以达到状态,并可以通过这种方式派遣我们的行动创建者。但是,借助this.props.selectBook( book )
及其灵活性,我们可以以一种简洁的方式打开状态和动作创建者。