React学习分享(九)

React + ts 进阶
在类组件中对状态约束 或 属性约束
状态:

import React, { Component } from 'react'
interface IState {
    name: string
}
export default class App extends Component<any, IState> {
    name!: string
    state = {
        name: "lihua"
    }
    render() {
        return (
            <div>
                app-{this.state.name.substring(0, 1).toUpperCase() + this.state.name.substring(1)}
                <button onClick={() => {
                    // 这里我们会发现,无论我们给name修改成什么类型的数据,都不会给我们报错,只有我们点击了,在浏览器运行了才知道
                    // 通过泛型 + interface, 第一个是对属性声明,第二个是状态声明 我们可以清楚的知道哪里报错了
                    // this.setState({
                    //     name: 1111
                    // })
                    this.setState({
                        name: "xiaoming"
                    })
                }}>点击</button>
            </div>
        )
    }
}

属性

import React, { Component } from 'react'
export default class App extends Component {
    render() {
        return (
            <div>
                <Child name="bbbb"/>
            </div>
        )
    }
}
interface IProps {
    name:string
}
class Child extends Component<IProps,any>{
    render(){
        return <div>
            child-{this.props.name}
        </div>
    }
}

在函数式组件中对状态约束 或 属性约束
状态:

import {useState} from 'react'
export default function App() {
    const [name, setname] = useState<string>("kerwin")
    return (
        <div>
            app-{name.substring(0,1).toUpperCase()+name.substring(1)}
            <button onClick={()=>{
                setname("xiaoming")
            }}>click</button>
        </div>
    )
}

属性:

import React from 'react'
export default function App() {
    return (
        <div>
            app
            <Child name="aaa"/>
        </div>
    )
}
interface IProps {
    name:string
}
// function Child(props:IProps){
//     return <div>child-{props.name}</div>
// }
const Child:React.FC<IProps> = (props)=>{
    return <div>child-{props.name}</div>
}

router v6 + react v18 + ts + redux :
src/router/index.tsx

import { RouteObject } from "react-router-dom";
import Cinema from '../views/Cinema'
import Detail from '../views/Detail'
import Film from '../views/Film'
import My from '../views/My'
const routes: RouteObject[] = [
    {
        path: '/',
        element: <Film />
    },
    {
        path: '/cinema',
        element: <Cinema />
    },
    {
        path: '/my',
        element: <My />
    }, {
        path: '/detail/:id',
        element: <Detail />
    }
]
export default routes

store/store.ts

import { createStore } from 'redux'
interface IAction {
    type: string,
    payload?: any
}
interface IState {
    isshow: boolean
}
const reducer = (preState: IState = {
    isshow: false
}, action: IAction) => {
    const { type } = action
    const newState = { ...preState }
    switch (type) {
        case "show":
            newState.isshow = true
            return newState
        case "hidden":
            newState.isshow = false
            return newState
        default:
            return preState;
    }
}
const store = createStore(reducer)
export default store

views/Cinema.tsx:

import React from 'react'
export default function Cinema() {
    return (
        <div>Cinema</div>
    )
}

views/Detail.tsx:

import React, { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { useParams } from 'react-router-dom'
export default function Detail() {
    const param = useParams()
    const dispath = useDispatch()
    const { isshow } = useSelector((state: any) => ({ isshow: state.isshow }))
    useEffect(() => {
        console.log(isshow);
        dispath({ type: "show" })
        console.log(isshow);
        return () => {
            dispath({ type: "hidden" })
            console.log(isshow);
        }
        // eslint-disable-next-line
    }, [])
    return (
        <div>Detail -{param.id}
            {isshow && <button>11111</button>}
        </div>
    )
}

views/Film.tsx:

import React, { useEffect, useState } from 'react'
import axios from 'axios'
import { useNavigate } from 'react-router-dom'
interface IItem {
    filmId: number,
    name: string
}
export default function Film() {
    const [list, setlist] = useState([])
    const navigate = useNavigate()
    useEffect(() => {
        axios({
            url: "https://m.maizuo.com/gateway?cityId=110100&pageNum=1&pageSize=10&type=1&k=5420934",
            headers: {
                'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.0","e":"16395416565231270166529"}',
                'X-Host': 'mall.film-ticket.film.list'
            }
        }).then((res) => {
            setlist(res.data.data.films)
        })
    }, [])
    return (
        <div>
            <ul>
                {
                    list.map((item: IItem) => {
                        return (
                            <li onClick={() => {
                                navigate(`/detail/${item.filmId}`)
                            }} key={item.filmId}>{item.name}</li>
                        )
                    })
                }
            </ul>
        </div>
    )
}

views/My.tsx:

import React from 'react'
export default function My() {
    return (
        <div>My</div>
    )
}

App.tsx:

import React from 'react';
import { useRoutes } from 'react-router-dom';
import './App.css';
import routes from './ts-redux/router';
function App() {
  const Views = () => useRoutes(routes)
  return (
    <Views />
  );
}
export default App;

index.tsx:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from "react-redux";
import store from './ts-redux/store/store';
const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <Provider store={store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </Provider>
);

ts其实挺好理解的,前面的基础弄好了,后面多敲熟悉熟悉,用多了就习惯了。

后面我再加一个有断言的例子:


import React, { Component } from 'react'
interface IState {
    text: string,
    list: string[]
}
export default class App extends Component<any, IState> {
    state = {
        text: "",
        list: []
    }
    myref = React.createRef<HTMLInputElement>()
    render() {
        return (
            <div>
                <input type="text" ref={this.myref} />
                <button onClick={() => {
                    // 可选连接符 ?.
                    // console.log(this.myref.current?.value);
                    // 断言
                    console.log((this.myref.current as HTMLInputElement).value);
                    this.setState({
                        list: [...this.state.list, (this.myref.current as HTMLInputElement).value]
                    })
                }}>click</button>
                {
                    this.state.list.map((item, index) => <li key={index}>{item}</li>)
                }
            </div>
        )
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值