이 글에서는 주로 react.js 사용법을 다루므로, 리액트가 생각보다 어렵지 않다는 것을 누구나 알 수 있습니다. 이제 이 글의 구체적인 내용을 살펴보겠습니다.
1, React은 모두 컴포넌트화되어 있습니다. #🎜 🎜#
React는 재사용 가능한 구성 요소라는 개념을 중심으로 설계되었습니다. 작은 구성요소를 정의하고 이를 결합하여 더 큰 구성요소를 형성합니다. 크기에 관계없이 모든 구성 요소는 다른 프로젝트에서도 재사용이 가능합니다.
React
가장 간단한 형태의 구성 요소는 일반적인 JavaScript입니다. 함수: # 🎜🎜#
function Button (props) { // 这里返回一个 DOM元素,例如: return <buttontype="submit">{props.label}</button>; } // 将按钮组件呈现给浏览器 ReactDOM.render(<Buttonlabel="Save" />, mountNode)
예 1: 위 코드를 편집하고 Ctrl+Enter를 눌러 실행합니다. (번역자 주: 번역에는 이 기능이 없습니다. 당분간 이 기능을 사용하시려면 원문을 참고해주세요. 아래 동일)
괄호 안의 버튼 라벨은 나중에 설명하겠습니다. 이제 걱정하지 마세요. ReactDOM에 대해서도 나중에 설명하겠지만, 이 예제와 이후의 모든 예제를 테스트하려면 위의 render 함수가 필요합니다. (React가 인계하고 제어하는 것은 대상 DOM 요소인 ReactDOM.render의 두 번째 매개변수입니다.) jsComplete REPL에서는 특수 변수 mountNode를 사용할 수 있습니다.
예제 1 에 대한 참고 사항:
구성 요소 이름의 첫 글자는 대문자로 표시됩니다(Button). 이는 HTML 요소와 React 요소의 혼합을 다루기 때문에 필요합니다. 소문자 이름은 HTML 요소용으로 예약되어 있습니다. 실제로 React 구성 요소의 이름을 "버튼"으로 지정하면 ReactDOM이 이 기능을 무시하고 일반 빈 HTML 버튼으로 렌더링한다는 것을 알 수 있습니다.
각 구성 요소는 HTML 요소와 마찬가지로 속성 목록을 받습니다. React에서는 이 목록을 속성이라고 합니다. 원하는 대로 함수 이름을 지정할 수 있습니다.
위 Button 함수 구성 요소의 반환 출력에 이상하게도 HTML처럼 보이는 코드 조각이 작성되었습니다. 이것은 실제로 JavaScript나 HTML이 아니며 솔직히 React.js도 아닙니다. 하지만 너무 인기가 많아서 React 애플리케이션의 기본값이 되었습니다. 이를 JSX라고 하며 이는 JavaScript 확장입니다. JSX도 절충안입니다! 위 함수에서 다른 HTML 요소를 반환하여 해당 요소가 어떻게 지원되는지 확인하세요(예: 텍스트 입력 요소 반환).
2
、JSX은 무엇을 출력하나요? 위의
예 1은 JSX 없이 사용할 수 있습니다# 🎜 🎜#은 다음과 같이 순수 React.js로 작성되었습니다:
function Button (props) { return React.createElement( "button", { type: "submit" }, props.label ); } // 要使用 Button,你可以这么做 ReactDOM.render( React.createElement(Button, { label:"Save" }), mountNode );
예제 2
: JSX를 사용하지 않고 React 구성 요소 작성React 최상위 API에서 createElement 함수는 주요 기능. 이것은 배워야 할 7개의 API 중 1개입니다. React의 API는 너무 작습니다.
DOM 자체에 태그 이름으로 지정된 요소를 생성하는 document.createElement 함수가 있는 것처럼 React의 createElement 함수는 고급 함수이자 문서입니다. createElement 동일한 기능이지만 React 구성 요소를 나타내는 요소를 만드는 데 사용할 수도 있습니다. 위의 예제 2에서 Button 구성 요소를 사용할 때 후자를 사용하고 있습니다.
document.createElement과 달리 React의 createElement는 생성된 요소의 하위 요소를 나타내는 두 번째 매개변수를 받은 후 동적 매개변수를 받습니다. 따라서 createElement는 실제로 트리를 생성합니다.
다음은 이에 대한 예입니다.
const InputForm = React.createElement( "form", { target: "_blank", action:"https://google.com/search" }, React.createElement("p",null, "Enter input and click Search"), React.createElement("input", {className: "big-input" }), React.createElement(Button, { label:"Search" }) ); // InputForm 使用 Button组件,所以我们需要这样做: function Button (props) { return React.createElement( "button", { type: "submit" }, props.label ); } // 然后我们可以通过 .render方法直接使用 InputForm ReactDOM.render(InputForm, mountNode);
例 3:React创建元素的 API
上面例子中的一些事情值得注意:
InputForm 不是一个 React组件;它仅仅是一个 React 元素。这就是为什么我们可以在ReactDOM.render 中直接使用它并且可以在调用时不使用
React.createElement函数在前两个参数后接收了多个参数。从第3个参数开始的参数列表构成了创建元素的子项列表。
我们可以嵌套 React.createElement调用,因为它是 JavaScript。
当这个元素不需要属性时,React.createElement的第二个参数可以为空或者是一个空对象。
我们可以在 React 组件中混合HTML 元素。你可以将 HTML 元素作为内置的 React组件。
React 的 API试图和 DOM API 一样,这就是为什么我们在 input 元素中使用 className 代替 class 的原因。我们都希望如果 React 的 API 成为 DOM API 本身的一部分,因为,你知道,它要好得多。
上述的代码是当你引入 React 库的时候浏览器是怎样理解的。浏览器不会处理任何 JSX 业务。然而,我们更喜欢看到和使用 HTML,而不是那些 createElement 调用(想象一下只使用document.createElement 构建一个网站!)。这就是 JSX 存在的原因。取代上述调用 React.createElement 的方式,我们可以使用一个非常简单类似于HTML 的语法:
const InputForm = <form target="_blank"action="https://google.com/search"> <p>Enter input and clickSearch</p> <inputclassName="big-input" name="q" /> <Buttonlabel="Search" /> </form>; // InputForm “仍然”使用 Button 组件,所以我们也需要这样。 // JXS 或者普通的表单都会这样做 function Button (props) { // 这里返回一个 DOM元素。例如: return <buttontype="submit">{props.label}</button>; } // 然后我们可以直接通过 .render使用 InputForm ReactDOM.render(InputForm, mountNode);
例 4:为什么在 React中 JSX 受欢迎(和例3 相比)
注意上面的几件事:
这不是 HTML 代码。比如,我们仍然可以使用 className 代替 class。
我们仍在考虑怎样让上述的 JavaScript看起来像是 HTML。看一下我在最后是怎样添加的。
我们在上面(例 4)中写的就是 JSX。然而,我们要将编译后的版本(例 3)给浏览器。要做到这一点,我们需要使用一个预处理器将 JSX 版本转换为 React.createElement 版本。
这就是 JSX。这是一种折中的方案,允许我们用类似 HTML 的语法来编写我们的 React 组件,这是一个很好的方法。
“Flux” 在头部作为韵脚来使用,但它也是一个非常受欢迎的应用架构,由 Facebook推广。最出名的是 Redux,Flux 和 React 非常合适。
JSX,可以单独使用,不仅仅适用于 React。
3、 你可以在 JavaScript的任何地方使用 JSX
在 JSX 中,你可以在一对花括号内使用任何 JavaScript 表达式。
const RandomValue = () => <p> { Math.floor(Math.random() * 100)} </p>; // 使用: ReactDOM.render(<RandomValue />,mountNode);
例 5:在 JSX中使用 JavaScript 表达式
任何 JavaScript 表达式可以直接放在花括号中。这相当于在 JavaScript 中插入 ${} 模板。
这是 JSX 内唯一的约束:只有表达式。例如,你不能使用 if 语句,但三元表达式是可以的。
JavaScript 变量也是表达式,所以当组件接受属性列表时(不包括 RandomValue组件,props 是可选择的),你可以在花括号里使用这些属性。我们在上述(例 1)的 Button 组件是这样使用的。
JavaScript 对象也是表达式。有些时候我们在花括号中使用 JavaScript对象,这看起来像是使用了两个花括号,但是在花括号中确实只有一个对象。其中一个用例就是将 CSS 样式对象传递给响应中的特殊样式属性:
const ErrorDisplay = ({message}) => <p style={ { color: 'red',backgroundColor: 'yellow' } }> {message} </p>; // 使用 ReactDOM.render( <ErrorDisplay message="These aren't thedroids you're looking for" />, mountNode );
例 6:一个对象传递特殊的 React样式参数
注意我解构的只是在属性参数之外的信息。这只是 JavaScript。还要注意上面的样式属性是一个特殊的属性(同样,它不是 HTML,它更接近 DOM API)。我们使用一个对象作为样式属性的值并且这个对象定义样式就像我们使用 JavaScript 那样(我们可以这样做)。
你可以在 JSX 中使用 React 元素。因为这也是一个表达式(记住,一个 React 元素只是一个函数调用):
const MaybeError = ({errorMessage}) => <p> {errorMessage &&<ErrorDisplay message={errorMessage} />} </p>; // MaybeError 组件使用 ErrorDisplay组件 const ErrorDisplay = ({message}) => <p style={ { color: 'red',backgroundColor: 'yellow' } }> {message} </p>; // 现在我们使用 MaybeError组件: ReactDOM.render( <MaybeError errorMessage={Math.random() >0.5 ? 'Not good' : ''} />, mountNode );
例 7:一个 React元素是一个可以通过 {} 使用的表达式
上述 MaybeError 组件只会在有errorMessage 传入或者另外有一个空的 p 才会显示 ErrorDisplay 组件。React 认为 {true}、 {false}
{undefined} 和 {null} 是有效元素,不呈现任何内容。
我们也可以在 JSX 中使用所有的JavaScript 的集合方法(map、reduce 、filter、 concat 等)。因为他们返回的也是表达式:
const Doubler = ({value=[1, 2, 3]}) => <p> {value.map(e => e * 2)} </p>; // 使用下面内容 ReactDOM.render(<Doubler />, mountNode);
例 8:在 {}中使用数组
请注意我是如何给出上述 value 属性的默认值的,因为这全部都只是 JavaScript。注意我只是在 p 中输出一个数组表达式。React 是完全可以的。它只会在文本节点中放置每一个加倍的值。
4、 你可以使用 JavaScript类写 React 组件
简单的函数组件非常适合简单的需求,但是有的时候我们需要的更多。React也支持通过使用 JavaScript 类来创建组件。这里 Button 组件(在例 1 中)就是使用类的语法编写的。
class Button extends React.Component { render() { return<button>{this.props.label}</button>; } } // 使用(相同的语法) ReactDOM.render(<Buttonlabel="Save" />, mountNode);
例 9:使用 JavaScript类创建组件
类的语法是非常简单的:定义一个扩展的 React.Component类(另一个你需要学习的 React 的顶级 API)。该类定义了一个单一的实例函数 —— render(),并使函数返回虚拟 DOM 对象。每一次我们使用基于类的 Button 组件(例如,通过 ),React 将从这个基于类的组件中实例化对象,并在 DOM 树中使用该对象。
这就是为什么上面的例子中我们可以在 JSX中使用 this.props.label 渲染输出的原因,因为每一个组件都有一个特殊的称为props 的 实例 属性,这让所有的值传递给该组件时被实例化。
由于我们有一个与组件的单个使用相关联的实例,所以我们可以按照自己的意愿定制该实例。例如,我们可以通过使用常规 JavaScript构造函数来构造它:
class Button extends React.Component { constructor(props) { super(props); this.id = Date.now(); } render() { return <buttonid={this.id}>{this.props.label}</button>; } } // 使用 ReactDOM.render(<Buttonlabel="Save" />, mountNode);
例 10:自定义组件实例
我们也可以定义类的原型并且在任何我们希望的地方使用,包括在返回的 JSX输出的内部:
class Button extends React.Component { clickCounter = 0; handleClick = () => { console.log(`Clicked: ${++this.clickCounter}`); } render() { return ( <button id={this.id}onClick={this.handleClick}> {this.props.label} </button> ); } } // 使用 ReactDOM.render(<Buttonlabel="Save" />, mountNode);
例 11:使用类的属性(通过单击保存按钮进行测试)
注意上述例 11 中的几件事情
handleClick 函数使用 JavaScript 新提出的 class-field syntax 语法。这仍然是 stage-2,但是这是访问组件安装实例(感谢箭头函数)最好的选择(因为很多原因)。然而,你需要使用类似 Babel 的编译器解码为 stage-2(或者仅仅是类字段语法)来让上述代码工作。 jsComplete REPL 有预编译功能。
// 错误:
onClick={this.handleClick()}
// 正确:
onClick={this.handleClick}
5、React中的事件:两个重要的区别
当处理 React 元素中的事件时,我们与 DOM API 的处理方式有两个非常重要的区别:
所有 React 元素属性(包括事件)都使用 camelCase 命名,而不是 lowercase。例如是 onClick 而不是 onclick。
我们将实际的 JavaScript 函数引用传递给事件处理程序,而不是字符串。例如是 onClick={handleClick} 而不是onClick="handleClick"。
React 用自己的对象包装 DOM对象事件以优化事件处理的性能,但是在事件处理程序内部,我们仍然可以访问 DOM对象上所有可以访问的方法。React 将经过包装的事件对象传递给每个调用函数。例如,为了防止表单提交默认提交操作,你可以这样做:
class Form extends React.Component { handleSubmit = (event) => { event.preventDefault(); console.log('Form submitted'); }; render() { return ( <formonSubmit={this.handleSubmit}> <buttontype="submit">Submit</button> </form> ); } } // 使用 ReactDOM.render(<Form />, mountNode);
例 12:使用包装过的对象
6、每一个 React组件都有一个故事:第 1 部分
以下仅适用于类组件(扩展 React.Component)。函数组件有一个稍微不同的故事。
首先,我们定义了一个模板来创建组件中的元素。
然后,我们在某处使用 React。例如,在 render 内部调用其他的组件,或者直接使用 ReactDOM.render。
然后,React 实例化一个对象然后给它设置 props 然后我们可以通过 this.props 访问。这些属性都是我们在第 2 步传入的。
因为这些全部都是 JavaScript,constructor方法将会被调用(如果定义的话)。这是我们称之为的第一个:组件生命周期方法。
接下来 React 计算渲染之后的输出方法(虚拟 DOM 节点)。
因为这是 React 第一次渲染元素,React将会与浏览器连通(代表我们使用 DOM API)来显示元素。这整个过程称为 mounting。
接下来 React 调用另一个生命周期函数,称为 componentDidMount。我们可以这样使用这个方法,例如:在 DOM 上做一些我们现在知道的在浏览器中存在的东西。在此生命周期方法之前,我们使用的 DOM 都是虚拟的。
一些组件的故事到此结束,其他组件得到卸载浏览器 DOM中的各种原因。在后一种情况发生时,会调用另一个生命周期的方法,componentWillUnmount。
任何 mounted 的元素的状态都可能会改变。该元素的父级可能会重新渲染。无论哪种情况,mounted 的元素都可能接收到不同的属性集。React 的魔力就是这儿,我们实际上需要的正是 React 的这一点!在这一点之前,说实话,我们并不需要 React。
组价的故事还在继续,但是在此之前,我们需要理解我所说的这种状态。
7、React组件可以具有私有状态
以下只适用于类组件。我有没有提到有人叫表象而已的部件 dumb?
状态类是任何 React 类组件中的一个特殊字段。React 检测每一个组件状态的变化,但是为了 React 更加有效,我们必须通过 React 的另一个 API 改变状态字段,这就是我们要学习的另一个 API —— this.setState:
class CounterButton extends React.Component { state = { clickCounter: 0, currentTimestamp: new Date(), }; handleClick = () => { this.setState((prevState) => { return { clickCounter:prevState.clickCounter + 1 }; }); }; componentDidMount() { setInterval(() => { this.setState({currentTimestamp: new Date() }) }, 1000); } render() { return ( <p> <buttononClick={this.handleClick}>Click</button> <p>Clicked:{this.state.clickCounter}</p> <p>Time:{this.state.currentTimestamp.toLocaleString()}</p> </p> ); } } // 使用 ReactDOM.render(<CounterButton />,mountNode);
例 13:setState的 API
这可能是最重要的一个例子因为这将是你完全理解 React基础知识的方式。这个例子之后,还有一些小事情需要学习,但从那时起主要是你和你的 JavaScript 技能。
让我们来看一下例 13,从类开始,总共有两个,一个是一个初始化的有初始值为 0 的 clickCounter 对象和一个从 new Date() 开始的 currentTimestamp。
另一个类是 handleClick 函数,在渲染方法中我们给按钮元素传入 onClick 事件。通过使用 setState 的 handleClick 方法修改了组件的实例状态。要注意到这一点。
另一个我们修改状态的地方是在一个内部的定时器,开始在内部的componentDidMount生命周期方法。它每秒钟调用一次并且执行另一个函数调用this.setState。
在渲染方法中,我们使用具有正常读语法的状态上的两个属性(没有专门的 API)。
现在,注意我们更新状态使用两种不同的方式:
通过传入一个函数然后返回一个对象。我们在 handleClick函数内部这样做。
通过传入一个正则对象,我们在在区间回调中这样做。
这两种方式都是可以接受的,但是当你同时读写状态时,第一种方法是首选的(我们这样做)。在区间回调中,我们只向状态写入而不读它。当有问题时,总是使用第一个函数作为参数语法。伴随着竞争条件这更安全,因为 setstate实际上是一个异步方法。
상태를 어떻게 업데이트해야 하나요? 업데이트하려는 값이 포함된 객체를 반환합니다. setState을 호출할 때 상태에서 하나의 속성을 전달하거나 전혀 전달하지 않습니다. setState는 실제로 전달한 함수 인수(반환 값)를 기존 상태와 병합하므로 완전히 괜찮습니다. 따라서 setState를 호출할 때 속성을 지정하지 않는다는 것은 속성을 변경하고 싶지는 않지만 삭제하지는 않는다는 의미입니다.
8, 반응반응합니다
반응합니다 이라는 이름은 상태 변경에 대한 반응에서 유래되었습니다(반응은 없지만 일정에도 있음). 여기에 농담이 있습니다. React의 이름은 Schedule로 지정해야 합니다!
그러나 어떤 컴포넌트의 상태가 업데이트되면 우리가 육안으로 관찰하는 것은 해당 업데이트에 대한 반응이며 자동으로 브라우저 DOM에 업데이트를 반영합니다( 필요한 경우).
렌더링 함수의 입력을 두 가지 유형으로 처리합니다.
상위 요소를 통해 전달된 속성 # 🎜🎜#
및 언제든지 업데이트 가능한 내부 비공개 상태
렌더링 함수에 대한 입력이 변경되면 출력이 변경될 수도 있습니다.
React 은 렌더링 기록을 저장하고 이전 렌더링과 다른 렌더링을 발견하면 두 렌더링의 차이를 계산합니다. 그것들은 차이점을 갖고 이를 DOM에서 수행되는 실제 DOM 작업으로 효과적으로 변환합니다.
9、 React는 귀하의 코드입니다. #React 를 우리가 사용하는 프록시로 생각할 수 있습니다. 브라우저와 통신합니다. 위의 현재 타임스탬프 표시를 예로 들어 보겠습니다. p#timestamp 요소를 찾아 업데이트하기 위해 수동으로 브라우저로 이동하여 매초마다 DOM API 작업을 호출할 필요 없이 구성 요소의 상태 속성만 변경하면 React가 우리를 대신하여 브라우저와 통신하는 작업을 수행합니다. 나는 이것이 React가 그토록 인기를 끄는 진짜 이유라고 믿습니다. 우리는 Mr. Browser(그리고 그것이 말하는 DOM 언어의 다양한 방언)와 이야기하는 것을 좋아하지 않습니다. React는 자발적으로 무료로 우리에게 전달됩니다!
10
, 모든 React구성 요소에는 스토리가 있습니다. 2부 #🎜🎜 #이제 구성요소의 상태를 알았으니 상태가 변경될 때 이 프로세스에 대한 마지막 몇 가지 개념을 살펴보겠습니다.
구성 요소의 상태가 업데이트되거나 상위 프로세스가 구성 요소에 전달하는 속성을 변경하기로 결정한 경우 구성 요소를 다시 렌더링해야 할 수 있습니다.후자가 발생하면 React
는 또 다른 수명 주기 메서드인 componentWillReceiveProps를 호출합니다.
상태 객체나 전달된 속성이 변경되면 React는 중요한 결정을 내려야 합니다. DOM에서 구성 요소를 업데이트해야 할까요? 이것이 바로 또 다른 중요한 수명 주기 메서드 shouldComponentUpdate를 호출하는 이유입니다. 이 방법은 실용적인 문제이므로 렌더링 프로세스를 직접 사용자 정의하거나 최적화해야 하는 경우 true 또는 false를 반환하여 이 질문에 대답해야 합니다.
맞춤형 shouldComponentUpdate없이 React의 기본 이벤트는 대부분의 경우 잘 처리됩니다.
우선, 이번에는 또 다른 생명주기 메소드인 componentWillUpdate가 호출됩니다. 그런 다음 React는 새로 렌더링된 출력을 계산하고 이를 마지막으로 렌더링된 출력과 비교합니다.
렌더링된 출력이 이전과 동일하면 React는 이를 처리하지 않습니다(Mr. Browser와 대화할 필요 없음).
차이가 있는 경우 React는 이전에 본 것처럼 브라우저에 차이점을 전달합니다. 어쨌든 업데이터가 발생하면 어떻게든(동일한 출력이 있더라도) React는 최종 수명 주기 메서드인 componentDidUpdate를 호출합니다. Lifecycle 메서드는 탈출구입니다. 특별한 작업을 하지 않으면 해당 항목 없이도 완전한 애플리케이션을 만들 수 있습니다. 애플리케이션에서 일어나는 일을 분석하고 ReactUpdate 의 성능을 더욱 최적화하는 데 매우 편리합니다. 이 기사는 여기에서 끝납니다. (자세한 내용을 보려면 PHP 중국어 웹사이트React 사용자 매뉴얼 열로 이동하여 알아보세요.) , 질문이 있으시면 아래에 메시지를 남겨주세요.
위 내용은 React.js를 어떻게 사용하나요? React.js의 간단한 사용법 소개(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!