reactにおける関数コンポーネントReact Hooks
13175 ワード
React Hooks
関数コンポーネント
hooksを使用する理由
16.8バージョンまでは関数コンポーネントはステータスを書くことができないため、classコンポーネントのコストが高いコードでネストするしかなく、フック関数(ライフサイクルが相対的に複雑すぎる)は16.8以降に関数コンポーネントのステータスを出した後、これらの弊害をよく解決しました.
useState
以前のバージョンでは関数コンポーネントはサポートされていませんでしたが、関数コンポーネントのサポートステータスを向上させるためにuseStateを使用できます.
const [name,setName] = useState("Riven")
主にこのuseStateを利用する方法も配列です.1つはRivenで、もう1つはこの状態を修正する方法f()です.自分でconsoleを見ることができます.log(useState("Riven"))上記のコードは、この状態とこの修正状態の方法を解構することで、状態にアクセスし、修正することができます.
// rcc => react component class
// rfc => react component function
import React,{useState} from 'react'
// useState
function App(){
console.log(useState("Riven"));
//
const [name,setName] = useState("Riven")
const [age,setAge] = useState(25)
return(
app----{name}---{age}
)
}
export default App
以上が関数コンポーネントの基本的な書き方です.多くの問題がありますか?関数コンポーネントのライフサイクルは?関数コンポーネントの値は通信しますか?クラスコンポーネントの書き方がないこれらはどのように書くべきですか?
後ろを見続けてください
todolistケース(関数コンポーネント)
まずinputボックスのvalue値をどのように取得しますか?
ここでは2つの方法とクラスコンポーネントの差が少ないです
import React,{useState} from 'react'
function App(){
const [text, setText] = useState("")
return(
{
// console.log(ev.target)
setText(ev.target.value)
}} />
)
}
export default App
この方法は複雑でuseRefを利用する必要がある
import React,{useState,useRef} from 'react'
const mytext = useRef(null)
{
// console.log(ev.target)
setText(ev.target.value)
}} ref={mytext} />
訪問するときはmytextを直接通ることができます.current.value value値を得る
import React,{useState,useRef} from 'react'
function App(){
const [text, setText] = useState("")
const mytext = useRef(null)
return(
{
// console.log(ev.target)
setText(ev.target.value)
}} ref={mytext} />
)
}
export default App
完全なtodolist
勉強するところに注意しなければならない
import React,{useState,useRef} from 'react'
function App(){
const [text, setText] = useState("")
const [list,setList] = useState(["111","222","333"])
const mytext = useRef(null)
//
const handledelclick = (index)=>{
var newlist = [...list]
newlist.splice(index,1)
setList(newlist)
}
return(
{
// console.log(ev.target)
setText(ev.target.value)
}} ref={mytext} value={text} />
{
list.map((item,index)=>
{item}
)
}
)
}
export default App
useEffect
関数コンポーネントにはライフサイクルuseEffectのようなライフサイクルはありませんが、ライフサイクルではありません.
データリクエストを関数コンポーネントのどこに置きますか?
まずuseEffectが2つのパラメータを受信することを知る必要があります.1つ目は処理関数で、2つ目は依存です.
最初のパラメータは、作成すると実行されます.
2番目のパラメータが入力された依存状態の変更も自動的に実行されます.
2番目のパラメータが入力された依存状態が空の場合は、値に相当します.
ステータス変更を送信しないと、最初の処理関数の実行がトリガーされます.
returnから出てきたこの関数は破棄時にのみ実行されます
useEffect(()=>{
console.log(" ");
var id = setInterval(()=>{
console.log(111);
},2000)
return ()=>{
console.log(" ")
clearInterval(id)
}
},[])
簡単なケースを見てみましょう
import React,{useState,useEffect} from 'react'
const Child = ()=>{
useEffect(()=>{
console.log(" ");
var id = setInterval(()=>{
console.log(111);
},2000)
return ()=>{
console.log(" ")
clearInterval(id)
}
},[])
return(
Child
)
}
const App = ()=>{
//useEffect( ,[ ])
const [text, setText] = useState("1111")
const [age, setAge] = useState(25)
// useEffect(()=>{
// console.log(" ")
// },[text])
// cdm
//[text] text
//
return(
App ----{text}
{age}
{
age===25?
:
null
}
)
}
export default App
実際の応用では関数コンポーネントがパラメータpropsを自動的に伝達し、propsのプロパティにアクセスできます.
props.match.params.myid props.history.goBack()
import React,{useState,useEffect} from 'react' import { PageHeader} from 'antd'; import axios from 'axios' const Preview = (props)=>{ const [title, settitle] = useState("") const [content, setcontent] = useState("") const [category, setcategory] = useState([]) useEffect(()=>{ axios.get(`http://localhost:8000/articles/${props.match.params.myid}`).then(res=>{ console.log(res.data) let {title,content,category} = res.data settitle(title) setcontent(content) setcategory(category) }) },[props]) return (
{ // console.log("back",this.props.history) props.history.goBack()// }} // title={title} subTitle={category.join("/")} /> ) } export default Preview
useCallback
防止因为组件重新渲染,导致方法被重新创建 ,起到缓存作用; 只有第二个参数 变化了,才重新声明一次
也就是只需要当需要某个状态改变的时候才让函数执行一次
import React,{useState,useCallback} from 'react'
export default function App() {
const [text,settext] = useState("1111")
const test = useCallback(
() => {
console.log(text)
},
[text],
)
test()
return (
App-{text}
)
}
useContext useReducer
まず、これら2つは、関数コンポーネント内で非親子通信を行うために使用される.
まず、これらの生産者を包むGlobalContextを作成する必要があります.
import React from 'react'
const GlobalContext = React.createContext()
export default GlobalContext
そして導入
import GlobalContext from './store'
全体コードは次のとおりです.
import React,{useReducer,useContext} from 'react'
import GlobalContext from './store'
import reducer from './store/reducer'
import axios from 'axios'
const Child1 = ()=>{
// useContext(GlobalContext)
// console.log(useContext(GlobalContext))
let {state,dispatch} = useContext(GlobalContext)
return (
child1-----{state.text}
)
}
const Child2 = ()=>{
let {state,dispatch} = useContext(GlobalContext)
return (
Child2----{state.text}
{
state.list.map(item=>
{item.title}
)
}
)
}
const App = ()=>{
const [state,dispatch] = useReducer(reducer,{
isShow:true,
list:[],
text:" "
}) //[ , ]
return (
)
}
export default App
ここは注意が必要だ
const [state,dispatch] = useReducer(reducer,{
isShow:true,
list:[],
text:" "
}) //[ , ]
このuseReducer(reducer)は実は1つの配列の中に2つの値があることに相当します.1つは共通の状態です.もう1つは共通の状態を変える方法です.
アクセス時にはusecontext(GlobalContext)に2つの値があります.1つはstate、もう1つはdispatchです.
const Child1 = ()=>{
// useContext(GlobalContext)
// console.log(useContext(GlobalContext))
let {state,dispatch} = useContext(GlobalContext)
return (
child1-----{state.text}
)
}
非同期もそれほど悪くない
const Child2 = ()=>{
let {state,dispatch} = useContext(GlobalContext)
return (
Child2----{state.text}
{
state.list.map(item=>
{item.title}
)
}
)
}
reducerファイル
const reducer = (prevstate,action)=>{
let {type,payload} = action
switch(type){
case "Change_text":
// ,
// prevstate.text
// var newstate = {...prevstate}
return {
...prevstate,
text:payload
} // immutable
case "Change_list":
return {
...prevstate,
list:payload
}
default:
return prevstate
}
}
export default reducer
関数コンポーネントの親子通信の問題
これはクラスコンポーネントとあまり差がありませんが、関数コンポーネントが自動的にパラメータpropsを転送するだけで、propsのプロパティに直接アクセスできます.
ペアレント(アトリビュート)
子の親(コールバック関数)
// ,
// -> ,
// -> , callback( )
import React,{useState} from 'react'
const Navbar = (props)=>{
console.log(props)
return
navbar-{props.myname}
}
const Sidebar = ()=>{
return
Sidebar
- 111111
- 222222
- 333333
}
const Child = (props)=>{
return
child --{props.children}
}
export default function App() {
const [show, setshow] = useState(false)
return (
{
console.log(" ")
setshow(!show)
}}/>
{
show?
:null
}
child-11111111
child-22222222
)
}