一、怎么定义一个组件。
组件分为无状态组件和类组件。
1、无状态组件
<div class="box"></div>
var App = ()=>{ //组件的首字母大写
return <div>app component</div>
}
ReactDom.render(<App />,document.getElementById("box"))
注意坑:return后面不能随意给空格和换行,会报错。解决方法:把return的内容用小括号包裹。
2、类组件
<div id="box"></div>
<script type="text/babel">
class App extends React.Component {
render(){
return <div>App component </div>
}
}
ReactDOM.render(<App />,document.getElementById("box"))
注意:写法上,必须得有render函数,且render里面必须返回一个根元素,否则会报错。
二、父组件给子组件传值
1、无状态组件传值
<div id="box"></div>
<script type="text/babel">
var list1 = ["aa","bb","cc"];
var list2 = ["js","jq","html"];
var list3 = ["orange","banana","apple"]
//定义一个list组件作为app组件的子组件
var List =(props)=>{ // props就是父组件传过来的值。
let {list} = props; //结构赋值写法,等价于list = props.list
return <ul>
{
list.map((item,index)=>{
return <li key={index}>{item}</li>
})
}
</ul>
}
var App = (props)=>{ //组件的首个字母大写
let {a,b,c,d}=props; // props就是父组件传过来的值。
console.log(a,b,c,d)
return <div>app component
<List list={list1} /> {/* list就是传给子组件的值 */}
<List list={list2} />
<List list={list3} />
</div>
}
var obj={a:1,b:2,c:3,d:4}
// obj就是传给app这个组件的数据
ReactDOM.render(<App {...obj} />,document.getElementById("box"))
2、类组件传值
<div id="box"></div>
<script type="text/babel">
var list1 = ["aa","bb","cc"];
var list2 = ["js","jq","html"];
var list3 = ["orange","banana","apple"]
class ShowList extends React.Component {
render(){
return <div>
<ul>
{
//类组件就是通过this.props来接收父组件传来的值
this.props.list.map((item,index)=>{
return <li key={index}>{item}</li>
})
}
</ul>
</div>
}
}
class App extends React.Component {
render(){
return <div>App component
<ShowList list={list1} /> {/* list就是传给子组件的值 */}
<ShowList list={list2} />
<ShowList list={list3} />
</div>
}
}
ReactDOM.render(<App />,document.getElementById("box"))
三、子组件给父组件传值
1、父组件写一个方法,把方法传给子组件
2、子组件向父组件传值 通过调用父组件方法传参
<div id="box"></div>
<script type="text/babel">
class Counter extends React.Component {
constructor(props){
super(props);
this.state ={
n: props.n
}
//this.increment = this.increment.bind(this);
}
static defaultProps ={ // 默认的props的n值是20
n:20
}
change(payload){ // payload 1 或 -1
this.setState({
n:this.state.n+payload
},()=>{
//子组件向父组件传值 调用父组件方法
this.props.changeSum(payload);
})
}
render(){
return <div>
<button onClick={this.change.bind(this,-1)}>-</button>
{this.state.n}
<button onClick={this.change.bind(this,1)}>+</button>
</div>
}
}
class App extends React.Component{
constructor(props){
super(props);
this.arr = [1,2,3]; //计数器的初始值
this.state ={
sum : this.arr.reduce((a,b)=>a+b)
}
this.changeSum = this.changeSum.bind(this)
}
changeSum(n){ //n来自于 子组件 -1 或 -1
this.setState({
sum:this.state.sum +n
})
}
render(){
let {sum} = this.state;
return <div>
{/*<Counter n={this.arr[0]} changeSum={this.changeSum} />
<Counter n={this.arr[1]} changeSum={this.changeSum} />
<Counter n={this.arr[2]} changeSum={this.changeSum} />*/}
{
this.arr.map((item,index)=>{
return <Counter key={index} n={item} changeSum={this.changeSum} />
})
}
{sum}
</div>
}
}
ReactDOM.render(<App />,document.querySelector("#box"));
</script>
四、非父子组件传值
方法一:使用pubsub插件,这个插件用于父子组件传值(npm官网链接)
发送数据:pubsub(“事件”,“数据”);
接收数据:pubsub.subscribe(“事件”,(事件,数据)=>{ console.log(数据) });
(1)安装插件
npm i pubsub-js
(2)引入pubsubJs
import pubsubJs from 'pubsub-js'
(3)使用pubsubJs
①发生数据
export default class componentName extends Component {
send(){
pubsubJs.publish("evt","haha"); //发送数据
}
render() {
return (
<div>
<button onClick={this.send}>按钮</button>
</div>
)
}
}
②接收数据
export default class componentName extends Component {
constructor(props){
super(props);
pubsubJs.subscribe("evt",(evt,data)=>{ //接收数据
console.log(data);
})
}
render() {
return <div className="two"></div>
}
}
五、不传值的时候如何设置默认值,或者如何手动设置没有传值的报错
1、设置默认值
(1)短路运算
this.state = {
n:this.props.n ||100
}
但这种方式有点low
(2)用static defaultProps
(static是静态属性,表示不用实例。用类名就可以访问属性和方法)
static defaultProps = {
// state的变量:你要设置的props的默认值
n:20
}
2、设置报错,详见使用propTypes