有条件地从 parent 禁用 child 的按钮 - React
Disable child's button from parent conditionally - React
我有一个 Paginator
child 组件,如果它在第一页上,我想禁用左箭头按钮,如果我在第一页上方,我想再次使其可点击。与右箭头按钮相同,但页码为 5。
这是我尝试为此解决方案编写的条件:
if (this.state.page <= 1) {
this.setState({
disabledPrev: true
})
} else {
this.setState({
disabledPrev: false
})
}
if (this.state.page >= 5) {
this.setState({
disabledNext: true
})
} else {
this.setState({
disabledNext: false
})
}
但是无论我把它放在哪里,它都不起作用。我认为问题出在生命周期方法的错误使用上。
完整代码如下:
App.js
import React from 'react';
import './App.css';
import Loading from './components/Loading/Loading';
import Header from './components/Header/Header';
import Table from './components/Table/Table';
import Paginator from './components/Paginator/Paginator';
const BASE_URL = 'https://api.udilia.com/coins/v1/'
export default class App extends React.Component{
constructor(props) {
super(props);
console.log('constructor');
this.state = {
currencies: null,
isDataReady: false,
page : 1,
disabledPrev: false,
disabledNext: false,
}
}
fetchCurrencies = (pageNumber) => {
fetch(`${BASE_URL}cryptocurrencies?page=${pageNumber}&perPage=20`)
.then(res => res.json())
.then(json => json.currencies)
.then(currencies => {
this.setState({
currencies: currencies,
isDataReady: true,
})
});
}
UNSAFE_componentWillMount() {
console.log('will mount', this.state.page);
}
componentDidUpdate() {
console.log('didUpdate', this.state.page);
}
componentDidMount() {
console.log('did mount', this.state.page);
//Here is the conditions
if (this.state.page <= 1) {
this.setState({
disabledPrev: true
})
} else {
this.setState({
disabledPrev: false
})
}
if (this.state.page >= 5) {
this.setState({
disabledNext: true
})
} else {
this.setState({
disabledNext: false
})
}
const {page} = this.state;
this.fetchCurrencies(page);
}
//here is the event handler, I change the page value from here
handlePaginationClick = (direction) => () => {
console.log('clicked', this.state.page);
let page = direction === 'next' ? this.state.page + 1 : this.state.page - 1;
this.setState({page})
this.fetchCurrencies(page);
}
render(){
console.log('render', this.state.page);
return (
!this.state.isDataReady
? <Loading />
: <div className="App">
<Header />
<Table
data={this.state.currencies}
/>
<Paginator
prev={this.handlePaginationClick('prev')}
next={this.handlePaginationClick('next')}
page={this.state.page}
disabledPrev={this.state.disabledPrev}
disabledNext={this.state.disabledNext}
/>
</div>
);
}
}
Paginator.js
import React from 'react';
export default function Paginator(props) {
return(
<div>
<button disabled={props.disabledPrev} onClick={() => props.prev()}> ← </button>
<span>page {props.page} of 10</span>
<button disabled={props.disabledNext} onClick={() => props.next()}> → </button>
</div>
)
}
<Paginator
prev={this.handlePaginationClick('prev')}
next={this.handlePaginationClick('next')}
page={this.state.page}
disabledPrev={this.state.page <= 0}
disabledNext={this.state.page >= 5}
/>
componentDidmount 上不需要以下 statements/Condition:
if (this.state.page <= 1) {
this.setState({
disabledPrev: true
})
} else {
this.setState({
disabledPrev: false
})
}
if (this.state.page >= 5) {
this.setState({
disabledNext: true
})
} else {
this.setState({
disabledNext: false
})
}
您不需要两个状态变量来处理左右箭头。
将 Paginator 组件修改为如下所示:
import React from "react";
export default function Paginator({ page, min = 1, max = 5 }) {
return (
<div>
<button disabled={page <= min} onClick={() => props.prev()}>
←
</button>
<span>page {props.page} of 10</span>
<button disabled={page >= max} onClick={() => props.next()}>
→
</button>
</div>
);
}
将 min
和 max
值传递给它。
<Paginator
prev={this.handlePaginationClick("prev")}
next={this.handlePaginationClick("next")}
page={this.state.page}
min={1}
max={5}
/>
试试这个
import React from 'react';
import './App.css';
import Loading from './components/Loading/Loading';
import Header from './components/Header/Header';
import Table from './components/Table/Table';
import Paginator from './components/Paginator/Paginator';
const BASE_URL = 'https://api.udilia.com/coins/v1/'
export default class App extends React.Component{
constructor(props) {
super(props);
console.log('constructor');
this.state = {
currencies: null,
isDataReady: false,
page : 1
}
}
fetchCurrencies = (pageNumber) => {
fetch(`${BASE_URL}cryptocurrencies?page=${pageNumber}&perPage=20`)
.then(res => res.json())
.then(json => json.currencies)
.then(currencies => {
this.setState({
currencies: currencies,
isDataReady: true,
})
});
}
UNSAFE_componentWillMount() {
console.log('will mount', this.state.page);
}
componentDidUpdate() {
console.log('didUpdate', this.state.page);
}
componentDidMount() {
console.log('did mount', this.state.page);
const {page} = this.state;
this.fetchCurrencies(page);
}
//here is the event handler, I change the page value from here
handlePaginationClick = (direction) => () => {
console.log('clicked', this.state.page);
let page = direction === 'next' ? this.state.page + 1 : this.state.page - 1;
this.setState({page})
this.fetchCurrencies(page);
}
render(){
console.log('render', this.state.page);
const {page} = this.state;
const disabledPrev = page <=1 ? true : false;
const disabledNext = page >=5 ? true : false;
return (
!this.state.isDataReady
? <Loading />
: <div className="App">
<Header />
<Table
data={this.state.currencies}
/>
<Paginator
prev={this.handlePaginationClick('prev')}
next={this.handlePaginationClick('next')}
page={page}
disabledPrev={disabledPrev}
disabledNext={disabledNext}
/>
</div>
);
}
}
我有一个 Paginator
child 组件,如果它在第一页上,我想禁用左箭头按钮,如果我在第一页上方,我想再次使其可点击。与右箭头按钮相同,但页码为 5。
这是我尝试为此解决方案编写的条件:
if (this.state.page <= 1) {
this.setState({
disabledPrev: true
})
} else {
this.setState({
disabledPrev: false
})
}
if (this.state.page >= 5) {
this.setState({
disabledNext: true
})
} else {
this.setState({
disabledNext: false
})
}
但是无论我把它放在哪里,它都不起作用。我认为问题出在生命周期方法的错误使用上。
完整代码如下:
App.js
import React from 'react';
import './App.css';
import Loading from './components/Loading/Loading';
import Header from './components/Header/Header';
import Table from './components/Table/Table';
import Paginator from './components/Paginator/Paginator';
const BASE_URL = 'https://api.udilia.com/coins/v1/'
export default class App extends React.Component{
constructor(props) {
super(props);
console.log('constructor');
this.state = {
currencies: null,
isDataReady: false,
page : 1,
disabledPrev: false,
disabledNext: false,
}
}
fetchCurrencies = (pageNumber) => {
fetch(`${BASE_URL}cryptocurrencies?page=${pageNumber}&perPage=20`)
.then(res => res.json())
.then(json => json.currencies)
.then(currencies => {
this.setState({
currencies: currencies,
isDataReady: true,
})
});
}
UNSAFE_componentWillMount() {
console.log('will mount', this.state.page);
}
componentDidUpdate() {
console.log('didUpdate', this.state.page);
}
componentDidMount() {
console.log('did mount', this.state.page);
//Here is the conditions
if (this.state.page <= 1) {
this.setState({
disabledPrev: true
})
} else {
this.setState({
disabledPrev: false
})
}
if (this.state.page >= 5) {
this.setState({
disabledNext: true
})
} else {
this.setState({
disabledNext: false
})
}
const {page} = this.state;
this.fetchCurrencies(page);
}
//here is the event handler, I change the page value from here
handlePaginationClick = (direction) => () => {
console.log('clicked', this.state.page);
let page = direction === 'next' ? this.state.page + 1 : this.state.page - 1;
this.setState({page})
this.fetchCurrencies(page);
}
render(){
console.log('render', this.state.page);
return (
!this.state.isDataReady
? <Loading />
: <div className="App">
<Header />
<Table
data={this.state.currencies}
/>
<Paginator
prev={this.handlePaginationClick('prev')}
next={this.handlePaginationClick('next')}
page={this.state.page}
disabledPrev={this.state.disabledPrev}
disabledNext={this.state.disabledNext}
/>
</div>
);
}
}
Paginator.js
import React from 'react';
export default function Paginator(props) {
return(
<div>
<button disabled={props.disabledPrev} onClick={() => props.prev()}> ← </button>
<span>page {props.page} of 10</span>
<button disabled={props.disabledNext} onClick={() => props.next()}> → </button>
</div>
)
}
<Paginator
prev={this.handlePaginationClick('prev')}
next={this.handlePaginationClick('next')}
page={this.state.page}
disabledPrev={this.state.page <= 0}
disabledNext={this.state.page >= 5}
/>
componentDidmount 上不需要以下 statements/Condition:
if (this.state.page <= 1) {
this.setState({
disabledPrev: true
})
} else {
this.setState({
disabledPrev: false
})
}
if (this.state.page >= 5) {
this.setState({
disabledNext: true
})
} else {
this.setState({
disabledNext: false
})
}
您不需要两个状态变量来处理左右箭头。
将 Paginator 组件修改为如下所示:
import React from "react";
export default function Paginator({ page, min = 1, max = 5 }) {
return (
<div>
<button disabled={page <= min} onClick={() => props.prev()}>
←
</button>
<span>page {props.page} of 10</span>
<button disabled={page >= max} onClick={() => props.next()}>
→
</button>
</div>
);
}
将 min
和 max
值传递给它。
<Paginator
prev={this.handlePaginationClick("prev")}
next={this.handlePaginationClick("next")}
page={this.state.page}
min={1}
max={5}
/>
试试这个
import React from 'react';
import './App.css';
import Loading from './components/Loading/Loading';
import Header from './components/Header/Header';
import Table from './components/Table/Table';
import Paginator from './components/Paginator/Paginator';
const BASE_URL = 'https://api.udilia.com/coins/v1/'
export default class App extends React.Component{
constructor(props) {
super(props);
console.log('constructor');
this.state = {
currencies: null,
isDataReady: false,
page : 1
}
}
fetchCurrencies = (pageNumber) => {
fetch(`${BASE_URL}cryptocurrencies?page=${pageNumber}&perPage=20`)
.then(res => res.json())
.then(json => json.currencies)
.then(currencies => {
this.setState({
currencies: currencies,
isDataReady: true,
})
});
}
UNSAFE_componentWillMount() {
console.log('will mount', this.state.page);
}
componentDidUpdate() {
console.log('didUpdate', this.state.page);
}
componentDidMount() {
console.log('did mount', this.state.page);
const {page} = this.state;
this.fetchCurrencies(page);
}
//here is the event handler, I change the page value from here
handlePaginationClick = (direction) => () => {
console.log('clicked', this.state.page);
let page = direction === 'next' ? this.state.page + 1 : this.state.page - 1;
this.setState({page})
this.fetchCurrencies(page);
}
render(){
console.log('render', this.state.page);
const {page} = this.state;
const disabledPrev = page <=1 ? true : false;
const disabledNext = page >=5 ? true : false;
return (
!this.state.isDataReady
? <Loading />
: <div className="App">
<Header />
<Table
data={this.state.currencies}
/>
<Paginator
prev={this.handlePaginationClick('prev')}
next={this.handlePaginationClick('next')}
page={page}
disabledPrev={disabledPrev}
disabledNext={disabledNext}
/>
</div>
);
}
}