如何在不刷新页面的情况下显示发布的数据?

How to display posted data without refresh the page?

我有一个简单的 React 应用程序, 可以 GET 和 POST 数据到 API。这是一个简单的图库,其中对图片进行了分类。

第一步,我从 API 获取所有画廊。很好用。

class Home extends Component {
constructor(props) {
    super(props);
    this.state = {
        galleries: [],
        isLoading: false,
        error: null,
    };
}

componentDidMount() {
    this.setState({ isLoading: true });

    fetch('http://.../gallery')
        .then((response) => response.json())
        .then((data)=>this.setState({galleries: data.galleries, isLoading: false}))
        .catch(error => this.setState({ error, isLoading: false}));
}

render() {
    const {galleries, isLoading, error} = this.state;
    if (error) {
        return <p>{error.message}</p>;
    }

    if (isLoading) {
        return <div className="loader-wrapper"><div className="loader"/></div>;
    }

    return (
        <div className="categories">
            { galleries.length > 0 ? galleries.map((gallery) => {
                return (
                    <Card key={gallery.path}>
                        ...
                    </Card>
                )}) : null
            }          
            <AddCategory/> 
        </div>
    );
}
}

下一步您可以创建新画廊。

class AddCategory extends Component {
constructor(props) {
    super(props);
    this.state = {
        modal: false,
        galleries: [],
        isLoading: false,
        error: null,
    };

    this.toggle = this.toggle.bind(this);

    this.handleClick = this.handleClick.bind(this);
}

toggle() {
    this.setState({
        modal: !this.state.modal
    });
}

handleClick(event) {
    event.preventDefault();
    this.setState({
        modal: !this.state.modal
    });
    this.setState({ isLoading: true });
    fetch('http://.../gallery', {
        method: 'POST',
        headers: {'Content-Type':'application/json'},
        body: JSON.stringify({"name": this.galleryName.value})
    })
        .then((response) => {
            if (response.ok) {
                return response.json();
            } else {
                throw new Error('Something went wrong ...')
            }
        })
        .then((data)=>this.setState({galleries: data.galleries, isLoading: false}))
        .catch(error => this.setState({ error, isLoading: false}));
}

render() {
    const {modal, isLoading, error} = this.state;

    if (error) {
        return <p>{error.message}</p>;
    }

    if (isLoading) {
        return <div className="loader-wrapper"><div className="loader"/></div>;
    }

    return (
        <Card className="add">
            <div className="link" onClick={this.toggle}>
                <CardBody>
                    <CardTitle>Add gallery</CardTitle>
                </CardBody>
            </div>
            <Modal isOpen={modal} toggle={this.toggle} className={this.props.className}>
                <div className="modal-header">
                    ...
                </div>
                <ModalBody>
                    <form className="form-inline addCategoryForm">
                        <div className="group">
                            <input type="text" ref={(ref) => {this.galleryName = ref}} id="inputGalleryName" name="galleryName" required/>
                            <label>name of the gallery</label>
                        </div>
                        <Button onClick={this.handleClick} color="success">Add</Button>
                    </form>
                </ModalBody>
            </Modal>
        </Card>
    );
}
}

问题是,在我点击“添加”按钮后,页面上没有任何反应,但在我刷新页面后,新画廊出现在列表中。

您是否知道为什么我在刷新页面后立即获得新图库,而不是在单击“添加”按钮后立即获得?

如果不刷新就看不到列表中的新画廊的原因是主要组件(在本例中为 Home 组件)没有被重新渲染,因为它没有任何变化状态变量,因此它不会更新页面。您在使用 POST 方法使用 fetch 获得响应后对 this.setState 的使用仅更新和重新呈现子组件 AddCategory.

在您的组件下方添加注释部分,以使 Home 组件重新呈现。

对于Home个组件;

class Home extends Component {
    constructor(props) {
        super(props);
        this.state = {
            galleries: [],
            isLoading: false,
            error: null,
        };

        // Add this method binding
        this.updateGalleries = this.updateGalleries.bind(this);
    }

    // Add this method
    updateGalleries = () => {
        this.setState({ isLoading: true });
        fetch('http://.../gallery')
        .then((response) => response.json())
        .then((data)=>this.setState({galleries: data.galleries, isLoading: false}))
        .catch(error => this.setState({ error, isLoading: false}));
    }

    componentDidMount() {
        ...
    }

    render() {
        ...

        return (
            <div className="categories">
                ...  
                /* Add updateGalleries funtion as props to AddCategory */
                <AddCategory updateGalleries={this.updateGalleries}/> 
            </div>
        );
    }
}

对于AddCategory个组件;

class AddCategory extends Component {
    constructor(props) {
        ...
    }

    toggle() {
        ...
    }

    handleClick(event) {
        ...
        // edit this field after response.json()
        .then((data)=>{
            this.setState({galleries: data.galleries, isLoading: false})
            this.props.updateGalleries();
        })
        .catch(error => this.setState({ error, isLoading: false}));
    }

    render() {
        ...
    }
}