如何从另一个组件中调用一个函数

时间:2017-10-21 13:51:44

标签: javascript reactjs

我在点击Add New Candidate按钮时附加一个文本框,我也想在点击保存按钮时调用NewCandidate组件的功能我尝试使用以下代码,但是它会抛出一个错误如果有人知道解决方案,请回答........................................... .................................................. ............................................

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0-alpha1/JSXTransformer.js"></script>    
    <script src="https://www.gstatic.com/firebasejs/3.9.0/firebase.js"></script>    
      </head>
  <body>
    <div id="root"></div>   
    <script type="text/jsx">
    class NewCandidate extends React.Component{
        validate(){
            alert()
        }       
        render(){
            return(
                <table>
                    <tr>
                        <th colSpan="2">Candidate details</th>
                    </tr>
                    <tr>
                        <th>Name</th><td><input type="text" ref="candName" /></td>
                    </tr>
                </table>
            )
        }
    }
    var CandidateList = [<NewCandidate />];

        class Interview extends React.Component{
            constructor(props){
                super();
                this.state={candidates:props.candidates}

            }
            updateCandidateList(newCandidate){
                var updatedCandidates=this.state.candidates;
                updatedCandidates.push(newCandidate);
                this.setState({candidates: updatedCandidates})  
            }
            render(){   
                return(
                    <div>
                        <Candidate candidates={this.state.candidates} />
                        <AddNewCandidate candidateList={this.updateCandidateList.bind(this)} />                     
                    </div>              
                )
            }       
        }
        class AddNewCandidate extends React.Component{
            constructor(){
                super()             
            }
            addNewCandidate(e){
                e.preventDefault();             
                this.props.candidateList(<NewCandidate />)
            }   
            render(){
                return(
                    <form>
                        <button onClick={this.addNewCandidate.bind(this)}>Add New Candidate</button>    
                        <button type="button" onClick={NewCandidate.validate.bind(this)}>Save</button>  
                    </form>
                )
            }
        }
        class Candidate extends React.Component{
            constructor(props){
                super(props);
            }
            render(){
                var items=this.props.candidates.map((item)=>{
                    return (<div>{item}</div>)
                });

                return(
                    <div>
                        {items}
                    </div>
                )
            }
        }   
        ReactDOM.render(<Interview candidates={CandidateList}/>,document.getElementById("root"));           
</script>
  </body>
</html>

2 个答案:

答案 0 :(得分:0)

这是一个例子。主App组件充当所有相关信息和操作的容器。然后,我们使用用于呈现数据的子组件,这些组件将使用从容器传递下来的方法来执行操作。

&#13;
&#13;
class NewCandidate extends React.Component {
  state = {
    name: ""
  };
  handleChange = evt => this.setState({
    name: evt.target.value
  });
  addCandidate = () => {
    const { name } = this.state;
    if (name === "") {
      return console.warn("input is empty");
    }
    return this.setState({
      name: '',
    }, () => this.props.add(name));
  };
  render() {
    if (this.props.display) {
      return (
        <div>
          <label>Name</label>
          <input
            type="text"
            value={this.state.name}
            onChange={this.handleChange}
          />
          <button onClick={this.addCandidate}>Add Candidate</button>
        </div>
      );
    }
    return null;
  }
}

const Candidate = ({ candidate }) => <div>{candidate.name}</div>;

class App extends React.Component {
  state = {
    showNewCandidateForm: false,
    candidates: [
      {
        id: 1,
        name: "Jeff"
      },
      {
        id: 2,
        name: "Andrew"
      },
      {
        id: 3,
        name: "Jess"
      }
    ]
  };
  addCandidate = name => {
    alert('validation here');
    const { candidates } = this.state;
    this.setState({
      showNewCandidateForm: false,
      candidates: [
        ...candidates,
        {
          id: candidates[candidates.length - 1].id + 1,
          name,
        }
      ]
    });
  };
  showNewCandidateForm = () => this.setState({
    showNewCandidateForm: true
  });
  hideNewCandidateForm = () => this.setState({
    showNewCandidateForm: false
  });
  render() {
    return (
      <div>
        <NewCandidate
          display={this.state.showNewCandidateForm}
          hide={this.hideNewCandidateForm}
          add={this.addCandidate}
        />
        {this.state.candidates.map(candidate => {
          return <Candidate key={candidate.id} candidate={candidate} />;
        })}
        <button onClick={this.showNewCandidateForm}>New Candidate</button>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
&#13;
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

请检查以下工作代码段。

&#13;
&#13;
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
    <script src="https://www.gstatic.com/firebasejs/3.9.0/firebase.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">

        class NewCandidate extends React.Component {
          constructor(props) {
            super(props);
            this.handleChange = this.handleChange.bind(this);
          }

          handleChange(e){
            e.preventDefault();
            this.props.handleCandidateChange(e.target.value, this.props.indexVal);
          }

          render(){
            return(
              <div>
                <table>
                    <tbody>
                    <tr>
                        <th colSpan="2">Candidate details</th>
                    </tr>
                    <tr>
                        <th>Name</th><td><input type="text" onChange={this.handleChange}/></td>
                    </tr>
                    </tbody>
                </table>
              </div>
            )
          }
        }


        class Interview extends React.Component {
          constructor(props){
            super(props);
            this.state = {
              candidates: [],
              values: []
            }
            this.addNewCandidate = this.addNewCandidate.bind(this);
            this.handleSave = this.handleSave.bind(this);
            this.handleCandidateChange = this.handleCandidateChange.bind(this);
          }

          handleCandidateChange(value, index) {
            const newValues = [].concat(this.state.values);
            newValues[index] = value;
            this.setState({values: newValues});
          }

          handleSave(e) {
            e.preventDefault();
            this.state.values.forEach((val, index) => {
              alert(`Validate ${index+1} value`);
            })
          }

          addNewCandidate(e) {
            e.preventDefault();
            const candidateList = [].concat(this.state.candidates);
            candidateList.push(<div key={`candidate-${candidateList.length}`}><NewCandidate indexVal={candidateList.length} handleCandidateChange={this.handleCandidateChange}/></div>)
            this.setState({candidates: candidateList});
          }

          render() {
            return (
              <div>
                {this.state.candidates}
                <button type="button" onClick={this.addNewCandidate}>Add New Candidate</button>
                <button type="button" onClick={this.handleSave}>Save</button>
              </div>
            )
          }
        }

        // render Interview component
        ReactDOM.render(<Interview />,document.getElementById("root"));
</script>
  </body>
</html>
&#13;
&#13;
&#13;