前端开发框架react 简述

嘉兴前端和移动端开发|前端开发 svg插件|前端开发面试题菜鸟教程
一:JSX
1)定义一个自定义组件:
**javascript代码**
var Driver = React.createClass({
render:functioin(){
return (
<div className=”divider”>
<h2>Questions</h2>
</div>
);
}
});
ReactDOM.render(<Divider/>,document.getElementById(‘container’));
2)使用动态值:
html 代码
//JSX将两个花括号之间的内容渲染为动态值:{}
var text = ‘question’;
<h2>{text}</h2>
//<h2>question</h2>
3)子节点:
React将开始标签与结束标签之间的所有子节点保存在一个名为this.props.chindren的特殊组件属性中
**html代码**
<h2>Question</h2>
//在这个例子中this.props.children==[“Question”]
e.g:
<scripttype=”text/babel”>
varDivider=React.createClass({
render:function(){
return (
<divclassName=”divider”>
<h2>{this.props.children}</h2>
</div>
)
}
});
ReactDOM.render(<Divider>Questions</Divider>,document.getElementById(‘container’));
</script>
//得到的html:
<divclass=”divider”data-reactid=”.0″>
<h2data-reactid=”.0.0″>Questionsss</h2>
</div>
4)事件:
事件名被规范化并统一用驼峰形式表示,如change变成了onChange,click变成了onClick,React自动绑定了组件所有方法的作用域,因此不需要手动绑定
html 代码
<script type=”text/babel”>
    var Divider = React.createClass({
        handleClick:function(){console.log(“test”)},
        render:function(){
            return <div style={{width:”200px”,height:”20px”,border:”1px solid green”}} onClick={this.handleClick}></div>
        }
    });
    ReactDOM.render(<Divider />,document.getElementById(‘container’));
</script>
5)特殊属性:
由于JSX会转换为原生的js函数,有些关键词我们无法使用,如for和class
html 代码
//for:
<label htmlFor=”for-text” ></label>
//class
<div className=”test-class”></div>
6)样式:
React把所有的内联样式都规范化为了驼峰形式,要添加一个自定义样式,只需简单地把驼峰形式的属性名及期望的css拼装为对象
html 代码
var styles = {
    borderColor: ‘#999’,
    borderThickness: ‘1px’,
}
React.renderComponent(<div style={styles} />)
二:组件的生命周期
1)实例化:
首次使用一个组件类时,下面这些方法依次被调用:
1.getDefaultProps
2.getInitialState
3.componentWillMount
4.render
5componentDidMount
getDefaultProps:
对于组件类来说,这个方法只会被调用一次,对于那些没有被父辈组件指定props属性的新建实例来说,这个方法返回的对象
可用于为实例设置默认的props值
*值得注意的是,任何复杂的值,比如对象和数组,都会在所有实例中共享,而不是拷贝或者克隆
getInitialState:
对于组件的每个实例来说,这个方法的调用次数有且只有一次。在这里你将有机会初始化每个实例的state.与getDefaultProps方法
不同的是,每次实例创建时该方法都会被调用,在这个方法里,你已经可以访问到this.props
componentWillMount:
该方法会在完成首次渲染之前被调用。这也是在render方法调用前可以修改组件state的最后一次机会
render:
这里你会创建一个虚拟DOM,用来表示组件的输出。对应一个组件来说,render是唯一一个必需的方法,并且有特定的规则,render方法要满足以下几点
1.只能通过this.props和this.state访问数据
2.可以返回null,false或者任何React组件
3.只能出现一个顶级组件(不能返回一组元素)
4.必需纯净,意味着不能改变组件的状态或者修改DOM的输出
render方法返回的结果不是真正的DOM,而是一个虚拟的表现,react随后会把它和真实的DOM做对比,来判断是否有必要做出修改
componentDidMount:
在render方法成功调用并且真实的DOM已经被渲染之后,你可以在componentDidMount内部通过this.getDOMNode()方法访问到它
e.g:假设需要在一个通过React渲染出的表单元素上使用jQueryUI的Autocomplete插件:
**javascript代码**
var datasource =[…];
var MyComponent = React.createClass({
render:function(){
return<input/>
},
componentDidMount:function(){
$(this.getDOMNode()).autocomplete({
sources:dtasource
});
}
});
// *注意,当React运行在服务端时,componentDidMount方法不会被调用
对于该组件类的所有后序应用,下面方法一次呗调用,注意:getDefaultProps方法已不在列表中
1.getInitialState
2.componentWillMount
3.render
4componentDidMount
2)存在期:
随着应用状态的改变,以及组件组件收到影响,以下方法依次被调用
1.componentWillReceiveProps
2.shouldComponentUpdate
3.componentWillUpdate
4.render
5.componentDidUpdate
componentWillReceiveProps:
在任意时刻,组件的props都可以通过父辈组件来更改,出现这种情况时,componentWillReceiveProps方法会被调用,你也将获得更改props对象及更新state的机会
javascript 代码
componentWillReceiveProps:function(nextProps){
if(nextProps.checked!==undefined){
this.setState({
checked:nextProps.checked
});
}
}
shouldComponentUpdate:
通过调用shouldComponentUpdate方法在组件渲染时进行精确优化,如果你确定某个组件或者它的任何子组件不需要渲染新的props或者state,则该方法适合返回false
返回false则是在告诉React要跳过调用render方法以及位于render前后的钩子函数:componentWillUpdate和componentDidUpdate
*在首次渲染期间或者调用了forceUpdate方法后,这个方法不会被调用
componentWillUpdate:
和componentWillMount方法类似,组件会在接收到新的props或者state进行渲染之前,调用该方法,注意,你不可以在该方法中更新state或者props,而应该借助
componentWillReceiveProps方法在运行时更新state
componentDidUpdate:
和componentDidMount方法类似,该方法给了我们更新已经渲染好的DOM的机会。
3)销毁&清理:
当组件被使用完成后,componentWillUnmount方法将会被调用,目的是给这个实例提供清理自身的机会
componentWillUnmount:
该方法会在组件被移除之前被调用,让你有机会做一些清理工作。你在coomponentDidMount方法中添加的所有任务都需要在该方法中撤销,比如创建的定时器或者添加的事件监听器
三:数据流
1)Props:
props就是properties的缩写,你可以使用它把任意类型的数据传递给组件。
**javascript代码**
//可以在挂载组件的时候设置它的Props
var surveys =[{title:”Superheros”}];
<ListSurveys surveys={surveys} />
//或者通过调用组件实例的setProps方法来设置其props
var surveys = [{title:”Superheroes”}];
var listSurveys = React.render(
<ListSurveys/>,
document.querySelector(‘body’)
);
listSurveys.setProps({surveys:surveys});
//只能在子组件上或者在组件树外调用setProps,千万别调用this.setProps或者直接修改
//this.props如果真的需要,请时候state
//可以通过this.props访问props,但绝对不能通过这种方式修改它,一个组件绝对不可以修改
//自己的props
//使用jsx的展开语法把props设置成一个对象
var ListSurveys = React.createClass({
render:function(){
varprops= {
one:’foo’,
two:’bar’
};
return<SurveyTable{props}/>
}
});
//Props还可以用来添加事件处理器
var SaveButton = React.createClass({
render:function(){
return (
<aclassName=”button save”onClick={this.handleClick}>Save</a>
);
},
handleClick:function(){}
});
2)PropTypes:
通过在组件中定义一个配置对象,React提供了一种验证props的方式
**javascript代码**
var SurveyTableRow = React.createClass({
    propTypes: {
        survey: React.PropTypes.shape({
            id: React.Proptypes.number.isRequired,
        }).isRequired,
        onClick: React.PropTypes.func,
    },
})
// 组件初始化时,如果传递的属性和propTypes不匹配,则会答应一个console.warn日志
// 如果是可选的配置,则可以去掉isRequired
// 在应用中使用propTypes并不是强制性的,但这提供了一种极好的方式来描述组件的API
3)getDefaultProps:
可以为组件添加getDefaultProps函数来设置属性的默认值。不过,这应该只针对那些非必需属性
**javascript代码**
var SurveyTable = React.createClass({
    getDefaultProps: function() {
        return {
            surveys: [],
        }
    },
})
//getDefaultProps 并不是在组件实例化时被调用的,而是在React.createClass
//调用时就被调用了,返回值被缓存起来。也就是说,不能在getDefaultProps
//中使用任何特定的实例数据
4)State:
每一个React组件都可以拥有自己的state,state与props的区别在于前者只存在于组件的内部。state可以用来确定一个元素的试图状态
**javascript代码**
var CountryDropdown = React.createClass({
    getInitialState: function() {
        return {
            showOptions: false,
        }
    },
    render: function() {
        var options
        if (this.state.showOptions) {
            options = (
                <ul className=”options”>
                    <li>A</li>
                    <li>B</li>
                    <li>C</li>
                </ul>
            )
        }
        return (
            <div className=”dropdown” onClick={this.handleClick}>
                <label>Make a choice</label>
            </div>
        )
    },
    handleClick: function() {
        this.setState({
            showOptioins: true,
        })
    },
})
//state可以通过setState来修改,也可以使用getInitialState方法提供一组默认值。
//只要setState被调用,render就会被调用。如果render函数的返回值有变化,虚拟
//DOM就会更新,真实的DOM也会被更新
//千万不能直接修改this.state ,永远记得要通过this.setState方法修改
###四:事件处理
1)事件和状态:
**javascript代码**
var SurveyEditor = React.createClass({
render:function(){
return (
<divclassName = ‘survey-editor’>
<div className=’row’>
<aside className=’sidebar col-md-3′>
<h2>Modules</h2>
<DraggableQuestions />
</aside>
<div className=’survey-canvas col-md-9′>
<div className={‘drop-zone well weill-drop-zone’}
onDragOver{this.handleDragOver}
onDragEnter={this.handleDragEnter}
onDragLeave={this.handleDragLeave}
onDrop = {this.handleDrop}
>
Drag and drop a module from the left
</div>
</div>
</div>
</div>
)
}
})
2)根据状态进行渲染:
**javascript代码**
var s = React.createClass({
getInitialState:function(){
return {
dropZoneEntered:false,
title:”,
introduction:”,
questions:[]
};
},
render:function(){
varquestions=this.state.questions;
vardropZoneEntered=”;
if(this.state.dropZoneEntered){
dropZonEntered=’drag-enter’;
}
return (
)
}
});
3)更新状态:
更新组件状态有两种方案:组件的setState方法和replaceState方法。replaceState用一个全新的state对象完整地替换掉原有的state。
**javascript代码**
getInitialState:function(){
return {
dropZoneEntered:false,
title:’test survey’,
introduction:’description’,
questions:[]
}
}
//这时,调用this.setState({title:’Fantastic Survey’}),仅仅影响this.state.title的值,
//而this.state.dropZoneEnter/introduction/question不会受影响
//而如果调用this.replaceState({title:”Fantastic Survey”})则会用新的对象替换掉整个
//state对象,同时把其他3个全部清除掉,这样做很可能中断render函数的执行
//现在使用this.setState可以实现上文提到的事件处理器方法
handleFormChange:function(formData){
this.setState(formData);
},
handleDragOver:function(ev){
ev.preventDefault();
},
handleDragEnter:function(){
this.setState({dropZoneEntered:true});
},
handleDragLeave:function(){
this.setState({dropZoneEntered:false});
},
handleDrop:function(ev){
varquestionType=ev.dataTransfer.getData(‘questionType’);
varquestion=this.state.questions;
questions=questions.concat({type:questionType});
this.setState({
questions:questions,
dropZoneEntered:false
});
}
//永远不要尝试通过setState或者replaceState意外的方式去修改state对象,类似this.state.saveInProgress = true 通常不是一个好主意,因为它无法通知
//React是否要重新渲染组件,而且可能导致下次调用setState时出现意外结果
4)事件对象:
**javascript代码**
var AnswerEssayQuestion = React.createClass({
    handleComplete: function(event) {
        this.callMethodOnProps(‘onCompleted’, event.target.value)
    },
    render: function() {
        return (
            <div className=”form-group”>
                <label className=”survey-item-label”>{this.props.label}</label>
                <div className=”survey-item-content”>
                    <textarea
                        className=”form-control”
                        rows=”3″
                        onBlur={this.handleComplete}
                    />
                </div>
            </div>
        )
    },
})
五:组件的复合
1)添加动态属性:
**javascript代码**
var AnswerRadioInput = React.createClass({
    propTypes: {
        id: React.PropTypes.string,
        name: React.PropTypes.string.isRequired,
        label: React.PropTypes.string.isRequired,
        value: React.PropTypes.string.isRequired,
        checked: React.PropTypes.bool,
    },
    getDefaultProps: function() {
        //对每个非必需的属性定义一个默认值
        return {
            id: null,
            checked: false,
        }
    },
})
2)追踪状态:
**javascript代码**
var AnswerRadioInput = React.createClass({
propTypes:{……},
getDefaultProps:function(){….},
getInitialState:function(){
varid=this.protps.id?this.props.id:uniqueId(‘radio-‘);
return {
checked:!!this.props.checked,
id:id,
name:id
}
},
render:function(){
<divclassName=”radio”>
<label htmlFor={this.props.id}>
<input type=”radio”
name={this.props.name}
id={this.props.id}
value={this.props.value}
checked={this.state.checked}/>
{this.props.label}
</label>
</div>
}
})
六:mixin
**javascript代码**
var Timer = React.createClass({
    mixins: [IntervalMixin(1000)],
    getInitialState: function() {
        return { secondsElapsed: 0 }
    },
    onTick: function() {
        this.setState({ secondsElapsed: this.state.secondsElapsed + 1 })
    },
    render: function() {
        return <div>Seconds Elapsed: {this.state.secondsElapsed}</div>
    },
})
var IntervalMixin = function(interval) {
    return {
        componentDidMount: function() {
            this._interval = setInterval(this.onTick, interval)
        },
        componentWillMount: function() {
            clearInterval(this._interval)
        },
    }
}
七:DOM操作
1)访问受控的DOM节点:
**javascript代码**
//componentDidMount内部并不是getDOMNode方法的唯一执行环境。事件处理器也可以在组件挂载
//后触发,所以你可以在事件处理器中调用getDOMNode
var RichText = React.createClass({
render:function(){
return<divref=”editableDiv”contentEditable=”true”
onkeyDown={this.handleKeyDown}>;
},
handleKeyDown:function(){
vareditor = this.refs.editableDiv.getDOMNode();
varhtml = editor.innerHTML;
}
})
###八:表单
1)无约束的组件:
**javascript代码**
//通过defaultValue设置input的默认值
var MyForm = React.createClass({
    rener: function() {
        return <input type=”text” defaultValue=”Hello World” />
    },
})
//上面这个例子展示的是无约束组件,组件的value并非由父组件设置,而是让<input/>自己
//控制自己的值,一个无约束的组件没有太大的用处,触发可以访问它的值,
//因此需要给input添加一个ref属性,以访问DOM节点的值
var MyForm = React.createClass({
    submitHandler: function(event) {
        event.preventDefault()
        var helloTo = this.refs.helloTo.getDOMNode().value
        console.log(helloTo)
    },
    render: function() {
        return (
            <form onSubmit={this.submitHandler}>
                <input ref=”helloTo” type=”text” defaultValue=”Hello World” />
                <button type=”submit”>Speak</button>
            </form>
        )
    },
})
//无约束组件可以用在基本的无须任何验证或者输入控件的表单中
2)约束组件:
约束组件的模式与React其他类型组件模式一直。表单组件的状态交由React组件控制,状态值被存储在React组件的state中
**javascript代码**
var MyForm = React.createClass({
    getInitialState: function() {
        return {
            helloTo: ‘Hello World’,
        }
    },
    handleChange: function(event) {
        this.setState({
            helloTo: event.target.value,
        })
    },
    submitHandler: function(event) {
        event.preventDefault()
        console.log(this.state.helloTo)
    },
    render: function() {
        renturn(
            <form onSubmit={this.submitHandler}>
                <input
                    type=”text”
                    value={this.state.helloTo}
                    onChange={this.handleChange}
                />
                <br />
                <button type=”submit”>Speak</button>
            </form>,
        )
    },
})
其中最显著的变化就是Input的值存储在父组件的state中
1)getInitialState设置defaultValue
2)input的值在渲染时被设置
3)input的值onChange时,change处理器被调用
4)change处理器更新state
5)在重新渲染时更新Input的值
3)表单事件:
React支持所有HTML事件。这些事件遵循驼峰命名的阅读,且会被转成合成事件,所有合成事件都提供了event.target来访问触发事件的DOM节点
**javascript代码**
handleEvent:function(syntheticEvent){<br />
var DOMNode = syntheticEvent.target;<br />
var newValue= DOMNode.value;<br />
}
4)文本框和Select:
<textarea/>被改得更像<input/>了,允许我们设置value和defaultValue
**javascript代码**
//非约束
<textarea defaultValue=”Hello world” />
//约束的
<textarea value={this.state.helloTo} onChange={this.handleChange} />
<select/>现在接受value和devaultValue来设置已选项
**javascript代码**
//非约束的
<select defaultValue=”8″>
<option value=”A”>First Option</option>
<option value=”B”>Second Option</option>
<option value=”C”>Third Option</option>
</select>
//约束的
<select value={this.state.helloTo} onChange={this.handleChange}>
<option value=”A”>First Option</option>
<option value=”B”>Second Option</option>
<option value=”C”>Third Option</option>
</select>
//React支持多选select,需要给value或者defaultValue传递一个数组
//非约束的
<select multiple=”true” defaultValue={[“A”,”B”]}>
<option value=”A”>First Option</option>
<option value=”B”>Second Option</option>
<option value=”C”>Third Option</option>
</select>
e.g:handleChnage循环检测DOM,并过滤出哪些选项被选中
**javascript代码**
var MyForm = React.createClass({
    getInitialState: function() {
        return {
            options: [‘B’],
        }
    },
    handleChange: function(event) {
        var checked = []
        var sel = event.target
        for (var i = 0; i < sel.length; i++) {
            var option = sel.options[i]
            if (option.selected) {
                checked.push(option.value)
            }
        }
        this.setState({ options: checked })
    },
    submitHandler: function(event) {
        event.preventDefault()
        console.log(this.state.options)
    },
    render: function() {
        return (
            <form onSubmit={this.submitHandler}>
                <select
                    multiple=”true”
                    value={this.state.options}
                    onChange={this.handleChange}
                >
                    <option value=”A”>First Option</option>
                    <option value=”B”>Second Option</option>
                    <option value=”C”>Third Option</option>
                </select>
                <br />
                <button type=”submit”>Speak</button>
            </form>
        )
    },
})
ReactDOM.render(<MyForm />, document.querySelector(‘#container’))
5)复选框和单选框:
要控制复选框或者单选框,就要控制他们的checked属性,也可以在非约束的复选框或者单选框中使用defaultChecked
**javascript代码**
//非约束的
var MyForm = React.createClass({
    submitHandler: function(event) {
        event.preventDefault()
        console.log(this.refs.checked.getDOMNode().checked)
    },
    render: function() {
        return (
            <form onSubmit={this.submitHandler}>
                <input ref=”checked” type=”checkbox” value=”A” defaultChecked=”ture” />
                <br />
                <button type=”submit”>Speak</button>
            </form>
        )
    },
})
//约束的
var MyForm = React.createClass({
    getInitialState: function() {
        return {
            checked: true,
        }
    },
    handleChange: function(event) {
        this.setState({ checked: event.target.checked })
    },
    submitHandler: function(event) {
        event.preventDefault()
        console.log(this.state.checked)
    },
    render: function() {
        return (
            <form onSubmit={this.submitHandler}>
                <input
                    type=”checkbox”
                    value=”A”
                    checked={this.state.checked}
                    onChange={this.handleChange}
                />
                <br />
                <button type=”submit”>Speak</button>
            </form>
        )
    },
})
6)多个表单元素与change处理器:
**javascript代码**
//通过bind传递其他参数
var MyForm = React.createClass({
    getInitialState: function() {
        return {
            given_name: ”,
            family_name: ”,
        }
    },
    handleChange: function(name, event) {
        var newState = {}
        newState[name] = event.target.value
        this.setState(newState)
    },
    submitHandler: function(event) {
        event.preventDefault()
        var words = [‘hi’, this.state.given_name, this.state.family_name]
        console.log(words.join(‘ ‘))
    },
    render: function() {
        return (
            <form onSubmit={this.submitHandler}>
                <label hrmlFor=”given_name”>Given Name:</label>
                <input
                    type=”text”
                    name=”given_name”
                    value={this.state.given_name}
                    onChange={this.handleChange.bind(this, ‘given_name’)}
                />
                <input
                    type=”text”
                    name=”family_name”
                    value={this.state.family_name}
                    onChange={this.handleChange.bind(this, ‘family_name’)}
                />
                <button type=”submit”>Speak</button>
            </form>
        )
    },
})
//使用DOMNode的name属性来判断需要更新哪个组件的状态
var MyForm = React.createClass({
    getInitialState: function() {
        return {
            given_name: ”,
            family_name: ”,
        }
    },
    handleChange: function(event) {
        var newState = {}
        newState[event.target.name] = event.target.value
        this.setState(newState)
    },
    submitHandler: function(event) {
        event.preventDefault()
        var words = [‘Hi’, this.state.given_name, this.state.family_name]
        console.log(words.join(‘ ‘))
    },
    render: function() {
        return (
            <form onSubmit={this.submitHandler}>
                <label hrmlFor=”given_name”>Given Name:</label>
                <input
                    type=”text”
                    name=”given_name”
                    value={this.state.given_name}
                    onChange={this.handleChange}
                />
                <label htmlFor=”family_name”>Family Name</label>
                <input
                    type=”text”
                    name=”family_name”
                    value={this.state.family_name}
                    onChange={this.handleChange}
                />
                <button type=”submit”>Speak</button>
            </form>
        )
    },
})
ReactDOM.render(<MyForm />, document.querySelector(‘#container’))
###九:动画
1)使用requestAnimationFrame实现间隔渲染:
javascript 代码
var Positioner = React.createClass({
    getInitialState: function() {
        return {
            position: 0,
        }
    },
    resolveAnimationFrame: function() {
        var timestamp = new Date()
        var timeRemaining = Math.max(
            0,
            this.props.animationCompleteTimestamp – timestamp,
        )
        if (timeRemaining > 0) {
            this.setState({ position: timeRemaining })
        }
    },
    componentWillUpdate: function() {
        if (this.props.animationCompleteTimestamp) {
            requestAnimationFrame(this.resolveAnimationFrame)
        }
    },
    render: function() {
        var divStyle = { left: this.state.position }
        return <div style={divStyle}>This will animate!</div>
    },
})
###十:性能优化
1)shouldComponentUpdate:
当一个组件更新时,无论是设置了新的props还是调用了setState方法或forceUpdate方法,React都会调用该组件所有子组件的render方法,有时候组件的render
方法会在不必要的情况下被调用。比如在渲染过程中并没有使用props或state的值,或者组件的props活state并没有在父组件重新渲染时发生改变。使用shouldComponentUpdate
方法可以帮助React正确地判断是否需要调用指定组件的render方法。
该方法返回一个布尔值,如果返回false就是告诉React不要调用组件的渲染方法,并使用之前渲染好的虚拟DOM,默认情况下返回true,并且在组件首次调用时
shouldComponentUpdate方法并不会被调用,接受两个参数,即新的props和新的state
javascript 代码
var SurveyEditor = React.createClass({
    shouldComponentUpdate: function(nextProps, nextState) {
        return nexProps.id !== this.props.id
    },
})
2)不可变性辅助插件:
在需要比较对象以确认是否更新时,使用不可变的数据结构能让你的shouldComponentUpdate方法变得更加简单。我们可以使用React.addons.update来确保
SurveyEditor组件的不可变性
javascript 代码
var update = React.addons.update;
var SurveyEditor = React.createClass({
handleDrop:function(ev){
varquestionType=ev.dataTransfer.getData(‘questionType’);
varquestions=update(this.state.questions,{
$push:[{type:questionType}]
});
this.setState({
questions:questions,
dropZoneEntered:false
});
},
handleQuestionChange:function(key,newQuestion){
varquestions=update(this.state.questions,{
$splice:[{key,1,newQuestion}]
});
this.setState({questions:questions});
},
handleQuestionRemove:function(key){
varquestions=update(this.state.questions,{
$splice:[{key,1}]
});
this.setState({questions:questions});
}
})
*React首页的一个例子,结合asp.net做后台,jsonp跨域请求数据,官网链接:http://reactjs.cn/react/docs/tutorial.html
Html:
html 代码
<!DOCTYPE html>
<html lang=”en”>
<head>
    <meta charset=”UTF-8″>
    <title>Document</title>
    <script src=”build/react.js”></script>
    <script src=”build/react-dom.js”></script>
    <script src=”build/jquery.js”></script>
    <script src=”build/browser.min.js”></script>
</head>
<body>
    <div id=”example”></div>
    <script type=”text/babel”>
varCommentForm=React.createClass({
getInitialState:function(){
return {author:”,text:”}
},
handleAuthorChange:function(e){
this.setState({author:e.target.value});
},
handleTextChange:function(e){
this.setState({text:e.target.value});
},
handleSubmit:function(e){
console.log(“Comment Form’s handleSubmit function”)
e.preventDefault();
varauthor=this.state.author.trim();
vartext=this.state.text.trim();
if(!text||!author){
return;
}
this.props.onCommentSubmit({author:author,text:text});
this.setState({author:”,text:”});
},
render:function(){
return (
<formclassName=”commentForm”onSubmit={this.handleSubmit}>
<input
type=”text”
placeholder=”Your name”
value ={this.state.author}
onChange={this.handleAuthorChange}
/>
<input
type=”text”
placeholder=”Say something…”
value = {this.state.text}
onChange = {this.handleTextChange}
/>
<input type=”submit” value =”Post”/>
</form>
)
}
})
varComment=React.createClass({
render:function(){
return (
<div>
{this.props.author}
{this.props.children}
<br/>
</div>
)
}
});
varCommentList=React.createClass({
render:function(){
varcommentNodes=this.props.data.map(function(comment){
return (
<Commentauthor={comment.author}>
{comment.text}
</Comment>
);
});
return (
<div>
{commentNodes}
</div>
)
}
});
varCommentBox=React.createClass({
loadCommentsFromServer:function() {
$.ajax({
url:this.props.url,
dataType:’jsonp’,
jsonp:”jsonpCallback”,
cache:false,
success:function(data) {
console.log(“ajax successfully called”);
this.setState({data:data});
}.bind(this),
error:function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
handleCommentSubmit:function(comment) {
varcomments=this.state.data;
comment.id=Date.now();
varnewComments=comments.concat([comment]);
this.setState({data:newComments});
$.ajax({
url:this.props.url,
dataType:’json’,
type:’POST’,
data:comment,
success:function(data) {
this.setState({data:data});
}.bind(this),
error:function(xhr, status, err) {
this.setState({data:comments});
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
getInitialState:function() {
return {data: []};
},
componentDidMount:function() {
this.loadCommentsFromServer();
},
render:function() {
return (
<divclassName=”commentBox”>
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm onCommentSubmit={this.handleCommentSubmit} />
</div>
);
}
});
ReactDOM.render(<CommentBoxurl=”https://www.rokub.com:65214/Data/getData”/>,document.getElementById(“example”))
</script>
</body>
</html>
asp:
html 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.web;
using System.web.Mvc;
using System.web.Script.Serialization;
namespace WebFactory.Controllers
{
publicclassDataController : Controller
{
//
// GET: /Api/
publicstaticList<books> blist = new List<books>() { newbooks() { id=”1″, author=”peter”, text=”peter text” }, newbooks() { id=”2″, author=”tom”, text=”tom text” } };
[HttpGet]
publicstringgetData()
{
stringjsonpCallback=Request.QueryString[“jsonpCallback”];
returnjsonpCallback+”(“+newJavaScriptSerializer().Serialize(blist)+”)”;
}
[HttpPost]
publicstringgetData(booksbook)
{
varresult=”failed”;
if (book!=null)
{
blist.Add(book);
result=”success”;
}
returnresult;
}
publicclassbooks
{
publicstringid { get; set; }
publicstringauthor { get; set; }
publicstringtext { get; set; }
}
}
}
前端开发需要学的框架|firefox 前端开发插件|前端开发搭建本地服务器热更新
» 本文来自:前端开发者 » 《前端开发框架react 简述》
» 本文链接地址:https://www.rokub.com/5190.html
» 您也可以订阅本站:https://www.rokub.com
赞(0)
64K

评论 抢沙发

评论前必须登录!