在router4.0的NavLink中的 isActive 的回调函数中,我使用this.setState改变组件的状态,这个回调会不停的执行

#1

在router4.0的NavLink中的 isActive 的回调函数中,我使用this.setState改变组件的状态,这个回调会不停的执行。

import React, {Component} from 'react';
import {
    BrowserRouter as Router,
    Link,
    NavLink
} from 'react-router-dom'
import './Home.scss';
import {topics} from '../../service/getData'
import Head from '../common/Head'

class Home extends Component {
    constructor(props) {
        super(props)
        this.state = {
            data: '', //列表数据
        }
        this.allData = this.allData.bind(this)
    }

//默认获取全部
    async componentWillMount() {
        //获取请求的类别
        let tabs = this.props.location.search.slice(1)
        let res = await topics({page: 1, tab: tabs, limit: 40})
        //这里没有问题
        this.setState({
            data: res.data
        })

    }
//获取全部
    async allData(match, location) {
        console.log(1)
        //获取请求的类别
        let tabs = location.search.slice(1)
        let allRes = await topics({page: 1, tab: tabs, limit: 40})

        this.setState({
            data: allRes.data
        })

    }

    render() {
        return (
            <div>
                <Head/>
                <div className="home-box">
                    <div className="home-content">
                        <div className="home-nav">
                            <NavLink exact to="/home?all" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'all') {
                                    //这里会不断的执行
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>全部</NavLink>
                            <NavLink exact to="/home?good" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'good') {
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>精华</NavLink>
                            <NavLink exact to="/home?share" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'share') {
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>分享</NavLink>
                            <NavLink exact to="/home?ask" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'ask') {
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>问答</NavLink>
                            <NavLink exact to="/home?job" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'job') {
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>招聘</NavLink>
                            <NavLink exact to="/home?dev" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'dev') {
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>客户端测试</NavLink>
                        </div>
                        <div>
                            {this.state.data == '' ? '' : this.state.data.map((item, key) => {
                                return (
                                    <div key={key}>
                                        <img src={item.author.avatar_url}/>
                                        <div>{item.reply_count}/{item.visit_count}</div>
                                        <div style={item.styleTab}>{item.resTab}</div>
                                        <div>{item.title}</div>
                                        <div>{item.last_reply_at}</div>
                                    </div>
                                )
                            })}
                        </div>
                    </div>
                </div>
            </div>
        );
    }
}

export default Home;
#3
import React, {Component} from 'react';
import {
    BrowserRouter as Router,
    Link,
    NavLink
} from 'react-router-dom'
import './Home.scss';
import {topics} from '../../service/getData'
import Head from '../common/Head'

class Home extends Component {
    constructor(props) {
        super(props)
        this.state = {
            data: '', //列表数据
        }
        this.allData = this.allData.bind(this)
    }

//默认获取全部
    async componentWillMount() {
        //获取请求的类别
        let tabs = this.props.location.search.slice(1)
        let res = await topics({page: 1, tab: tabs, limit: 40})
        //这里没有问题
        this.setState({
            data: res.data
        })

    }
//获取全部
    async allData(match, location) {
        console.log(1)
        //获取请求的类别
        let tabs = location.search.slice(1)
        let allRes = await topics({page: 1, tab: tabs, limit: 40})

        this.setState({
            data: allRes.data
        })

    }

    render() {
        return (
            <div>
                <Head/>
                <div className="home-box">
                    <div className="home-content">
                        <div className="home-nav">
                            <NavLink exact to="/home?all" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'all') {
                                    //这里会不断的执行
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>全部</NavLink>
                            <NavLink exact to="/home?good" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'good') {
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>精华</NavLink>
                            <NavLink exact to="/home?share" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'share') {
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>分享</NavLink>
                            <NavLink exact to="/home?ask" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'ask') {
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>问答</NavLink>
                            <NavLink exact to="/home?job" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'job') {
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>招聘</NavLink>
                            <NavLink exact to="/home?dev" activeClassName="selected" isActive={(match, location) => {
                                if (location.search.slice(1) === 'dev') {
                                    this.allData(match, location)
                                    return true
                                }
                                return false
                            }}>客户端测试</NavLink>
                        </div>
                        <div>
                            {this.state.data == '' ? '' : this.state.data.map((item, key) => {
                                return (
                                    <div key={key}>
                                        <img src={item.author.avatar_url}/>
                                        <div>{item.reply_count}/{item.visit_count}</div>
                                        <div style={item.styleTab}>{item.resTab}</div>
                                        <div>{item.title}</div>
                                        <div>{item.last_reply_at}</div>
                                    </div>
                                )
                            })}
                        </div>
                    </div>
                </div>
            </div>
        );
    }
}

export default Home;
#4

那就不要放在這裡調用setState

#5

但是我需要在点击NavLink的时候,去改变一个state的值,然后去获取一些数据。就是一个导航栏

#6

你可以監聽路由變化啊,然後去做不同的請求

#7

没错啊,就是在监控路由的变化。 在isActive这个回调当中,我执行了this.allData这个方法。在这个方法中,我去获取了路由的location.search的值,并对他进行截取,去掉了前面的问号,然后去请求的数据。。。。。最后将获取到的数据通过this.setState设置给state。然后渲染。。。。感觉逻辑没有错啊。。。但是,只要一加上this.setState的话,就会不断的执行。。。而使用this.state.data = res 的话,却会慢一步。

#8

我是說你用其他方法監聽路由變化,不要在isActive里運行,例如使用history.listen