通过道具传递功能后进行反应并检查条件

时间:2018-08-02 10:59:19

标签: javascript json ajax reactjs

很长一段时间以来,我一直在与我的应用程序战斗,但是进展缓慢,但是我仍然对一件事有疑问 我想将功能思想道具从表单组件传递到列表组件,此后,我想检查是否单击了按钮添加(如果是),然后我希望在列表组件内启动函数getMovie()并将另一个请求发送到json数据库。使用edit和remove,它就像在相同组件中一样工作,通过添加按钮,它有点棘手。

问题是,如果我只写

else if (this.props.addClick) {
                this.getMovie();
        }

它不断地向数据库发送请求

下面是我的代码

表单组件

class Form extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            name: '',
            type: '',
            description: '',
            id: '',
            movies: [],
            errors: "",
        }
    }

handleSubmit = e => {
        e.preventDefault()
        const url = `http://localhost:3000/movies/`;
        if (this.state.name != "" && this.state.type != "" && this.state.description != "") {
            axios
                .post(url, {
                    name: this.state.name,
                    type: this.state.type,
                    description: this.state.description,
                    id: this.state.id,
                })
                .then(res => {
                    this.setState({
                        movies: [this.state.name, this.state.type, this.state.description, this.state.id]
                    })
                })
                .then(this.setState({
                isButtonRemoveClicked: true
            }))
        }
        else {
            this.setState({
                errors:"Please, Fill all forms above"
            })
        }

    }

return (
            <div>
                <form onSubmit={this.handleSubmit}>
                    <input type="text" placeholder="Movie" onChange={this.handleChangeOne}/>
                    <input type="text" placeholder="Type of movie" onChange={this.handleChangeTwo}/>
                    <textarea placeholder="Description of the movie"
                              onChange={this.handleChangeThree}></textarea>
                    <input id="addMovie" type="submit" value="Add movie" ></input>
                    <p>{this.state.errors}</p>
                </form>
                <List removeClick={this.handleRemove} editClick={this.editMovie} addClick={this.handleSubmit}/>
            </div>
        )

列表组件

class List extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            movies: [],
            isButtonRemoveClicked: false,
        }
    }

    componentDidMount() {
        this.getMovie()
    }

    componentDidUpdate() {
        if (this.state.isButtonRemoveClicked === true) {
            this.getMovie();
            this.timer = setTimeout(() => {
                this.setState({
                    isButtonRemoveClicked: false
                })
            }, 10)
        }
        else if (this.props.addClick === true) {
                this.getMovie();
        }
    }

    componentWillUnmount() {
        clearTimeout(this.timer)
    }


    getMovie = () => {
        const url = `http://localhost:3000/movies`;
        axios
            .get(url)
            .then(res => {
                const movies = res.data;
                this.setState({
                    movies: movies,
                })
            })
            .catch((err) => {
                console.log(err);
            })
    }

3 个答案:

答案 0 :(得分:2)

没有神奇的东西;) 您开始从componentDidUpdate()加载数据...数据加载,再次触发componentDidUpdate ...

不要以这种方式处理事件。

答案 1 :(得分:1)

如果您的主要目标是从父组件中调用子组件中的函数,则可以使用引用。

代码示例:-

class Form extends React.Component {
constructor(props) {
    super(props)
    this.state = {
        name: '',
        type: '',
        description: '',
        id: '',
        movies: [],
        errors: "",
    }
} 
handleSubmit = e => {
        e.preventDefault()
        const url = `http://localhost:3000/movies/`;
        if (this.state.name != "" && this.state.type != "" && this.state.description != "") {
            axios
                .post(url, {
                    name: this.state.name,
                    type: this.state.type,
                    description: this.state.description,
                    id: this.state.id,
                })
                .then(res => {
                    this.setState({
                        movies: [this.state.name, this.state.type, this.state.description, this.state.id]
                    })
                })
                .then(
                this.list.getMovie();   // call child function here
                this.setState({
                isButtonRemoveClicked: true
            }))
        }
        else {
            this.setState({
                errors:"Please, Fill all forms above"
            })
        }

    }

return (
            <div>
                <form onSubmit={this.handleSubmit}>
                    <input type="text" placeholder="Movie" onChange={this.handleChangeOne}/>
                    <input type="text" placeholder="Type of movie" onChange={this.handleChangeTwo}/>
                    <textarea placeholder="Description of the movie"
                              onChange={this.handleChangeThree}></textarea>
                    <input id="addMovie" type="submit" value="Add movie" ></input>
                    <p>{this.state.errors}</p>
                </form>
                <List
                    ref={list => this.list=list }  // Create ref here
                    removeClick={this.handleRemove}
                    editClick={this.editMovie}
                    addClick={this.handleSubmit}/>
            </div>
        )

并且在列表组件中,无需使用componentDidUpdate getMovie()调用。

class List extends React.Component {
constructor(props) {
    super(props)
    this.state = {
        movies: [],
        isButtonRemoveClicked: false,
    }
}

componentDidMount() {
    this.getMovie()
}

getMovie = () => {
    const url = `http://localhost:3000/movies`;
    axios
        .get(url)
        .then(res => {
            const movies = res.data;
            this.setState({
                movies: movies,
            })
        })
        .catch((err) => {
            console.log(err);
        })
}

答案 2 :(得分:0)

我认为您正在以过于复杂的方式处理事件。您为什么不从List组件内部举起道具,而只是在Form中触发所需的行为?例如:

class List extends React.Component {

  handleAddClick() {
    this.props.onAddClick()
  }

  handleEditClick() {
    this.props.onEditClick()
  }

  handleRemoveClick() {
    this.props.onRemoveClick()
  }

  render() {
    return (
      <div>
        <button onClick={() => this.handleAddClick()}>Add</button>
        <button onClick={() => this.handleEditClick()}> Edit</button>
        <button onClick={() => this.handleRemoveClick()} > Remove</button>
      </div>
  })
}

class Form extends React.Component {

  getMovie() {
    // Make AXIOS request
  }

  handleAdd() {
    this.getMovie();
  }

  handleRemove() {
    // REMOVE CODE
  }

  handleEdit() {
    // EDIT CODE
  }

  render() {
    <form>
      {/* Form elements */}
      <List
        onAddClick={() => this.handleAdd()}
        onRemoveClick={() => this.handleRemove()}
        onEditClick={() => this.handleEdit()}
        />
  </form>
    }
}