Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何更新父项';你的状态如何?_Javascript_Reactjs_Web Deployment - Fatal编程技术网

Javascript 如何更新父项';你的状态如何?

Javascript 如何更新父项';你的状态如何?,javascript,reactjs,web-deployment,Javascript,Reactjs,Web Deployment,我的结构如下: Component 1 - |- Component 2 - - |- Component 4 - - - |- Component 5 Component 3 组件3应根据组件5的状态显示一些数据 由于道具是不可变的,我不能简单地将其状态保存在组件1中并转发它,对吗?是的,我读过,但我不想用它。我希望用react就可以解决这个问题。我错了吗?对于子-父通信,您应该将设置状态的函数从父级传递到子级,如下所示 class Parent extends Rea

我的结构如下:

Component 1

 - |- Component 2


 - - |- Component 4


 - - -  |- Component 5

Component 3
组件3应根据组件5的状态显示一些数据


由于道具是不可变的,我不能简单地将其状态保存在组件1中并转发它,对吗?是的,我读过,但我不想用它。我希望用react就可以解决这个问题。我错了吗?

对于子-父通信,您应该将设置状态的函数从父级传递到子级,如下所示


class Parent extends React.Component {
  constructor(props) {
    super(props)

    this.handler = this.handler.bind(this)
  }

  handler() {
    this.setState({
      someVar: 'some value'
    })
  }

  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <Button onClick = {this.props.handler}/ >
  }
}


类父类扩展了React.Component{
建造师(道具){
超级(道具)
this.handler=this.handler.bind(this)
}
handler(){
这是我的国家({
someVar:“一些值”
})
}
render(){
返回
}
}
子类扩展了React.Component{
render(){
返回
}
}
通过这种方式,子级可以通过使用props传递的函数调用来更新父级的状态

但您必须重新考虑组件的结构,因为据我所知,组件5和组件3并不相关


一种可能的解决方案是将它们包装在一个更高级别的组件中,该组件将包含组件1和3的状态。此组件将通过道具设置较低级别的状态。

我喜欢关于传递函数的答案。这是一种非常方便的技术

另一方面,您也可以使用pub/sub或使用一个变量(dispatcher)来实现这一点。这个理论非常简单。让组件5发送组件3正在侦听的消息。然后,组件3更新其状态,从而触发重新渲染。这需要有状态的组件,这取决于您的视点,可能是也可能不是反模式。我个人反对他们,更希望有其他东西从上到下监听调度和更改状态(Redux可以做到这一点,但它添加了额外的术语)

从'flux'导入{Dispatcher}
从“React”导入{Component}
const dispatcher=new dispatcher()
//构成部分3
//为了简洁起见,省略了一些方法,例如构造函数
类StatefulParent扩展组件{
状态={
文本:“foo”
} 
componentDidMount(){
dispatcher.register(调度=>{
如果(dispatch.type==='change'){
this.setState({text:'bar'})
}
}
}
render(){
返回{this.state.text}
}
}
//单击处理程序
const onClick=event=>{
调度({
键入:“更改”
})
}
//示例中的组件5
const StatelessChild=props=>{
返回单击我
}

带有Flux的dispatcher bundle非常简单。它只是注册回调,并在发生任何调度时调用回调,传递调度上的内容(在上面的简单示例中,调度没有
有效负载
,只是一个消息id)。您可以将其适应于传统的发布/订阅(例如,使用events中的EventEmitter或其他版本)如果这对您更有意义,则非常容易。

每当您需要在任何级别的子级与父级之间进行通信时,最好使用上下文。在父级组件中定义子级可以调用的上下文,例如:

在父组件中,在您的示例组件3中

static childContextTypes = {
    parentMethod: React.PropTypes.func.isRequired
};

getChildContext() {
    return {
        parentMethod: (parameter_from_child) => this.parentMethod(parameter_from_child)
    };
}

parentMethod(parameter_from_child){
    // Update the state with parameter_from_child
}
现在在子组件(在您的例子中是组件5)中,只需告诉这个组件它想要使用其父组件的上下文

static contextTypes = {
    parentMethod: React.PropTypes.func.isRequired
};

render() {
    return(
        <TouchableHighlight
            onPress = {() => this.context.parentMethod(new_state_value)}
            underlayColor='gray' >

            <Text> update state in parent component </Text>

        </TouchableHighlight>
)}
静态上下文类型={
父方法:React.PropTypes.func.isRequired
};
render(){
返回(
this.context.parentMethod(新状态值)}
参考底色=“灰色”>
父组件中的更新状态
)}

您可以在中找到演示项目。

我找到了以下工作解决方案,将onClick函数参数从子组件传递到父组件:

 class Parent extends React.Component {
  constructor(props) {
    super(props)
    // without bind, replaced by arrow func below
  }

  handler = (val) => {
    this.setState({
      someVar: val
    })
  }

  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <Button onClick = {() => this.props.handler('the passing value')}/ >
  }
}
传递方法的版本()

//ChildB组件
类ChildB扩展了React.Component{
render(){
var handleToUpdate=this.props.handleToUpdate;
返回(handleToUpdate('someVar')}>
推我
)
}
}
//父组件
类ParentA扩展了React.Component{
建造师(道具){
超级(道具);
var handleToUpdate=this.handleToUpdate.bind(this);
变量arg1='';
}
handleToUpdate(someArg){
警报('我们将参数从子级传递到父级:'+someArg);
this.setState({arg1:someArg});
}
render(){
var handleToUpdate=this.handleToUpdate;
返回(
)
}
}
if(document.querySelector(“demo”)){
ReactDOM.render(
,
文档查询选择器(“演示”)
);
}

具有传递箭头功能的版本

//ChildB component
class ChildB extends React.Component {

    render() {

        var handleToUpdate = this.props.handleToUpdate;
        return (<div>
          <button onClick={() => handleToUpdate('someVar')}>
            Push me
          </button>
        </div>)
    }
}

//ParentA component
class ParentA extends React.Component {
    constructor(props) {
        super(props);
    }

    handleToUpdate = (someArg) => {
            alert('We pass argument from Child to Parent: ' + someArg);
    }

    render() {
        return (<div>
            <ChildB handleToUpdate = {this.handleToUpdate} /></div>)
    }
}

if(document.querySelector("#demo")){
    ReactDOM.render(
        <ParentA />,
        document.querySelector("#demo")
    );
}
//ChildB组件
类ChildB扩展了React.Component{
render(){
var handleToUpdate=this.props.handleToUpdate;
返回(
handleToUpdate('someVar')}>
推我
)
}
}
//父组件
类ParentA扩展了React.Component{
建造师(道具){
超级(道具);
}
handleToUpdate=(someArg)=>{
警报('我们将参数从子级传递到父级:'+someArg);
}
render(){
返回(
)
}
}
if(document.querySelector(“demo”)){
ReactDOM.render(
,
文档查询选择器(“演示”)
);
}

我找到了以下可行的解决方案,可以将onClick函数参数从子组件传递到带有参数的父组件:

父类:

class Parent extends React.Component {
constructor(props) {
    super(props)

    // Bind the this context to the handler function
    this.handler = this.handler.bind(this);

    // Set some state
    this.state = {
        messageShown: false
    };
}

// This method will be sent to the child component
handler(param1) {
console.log(param1);
    this.setState({
        messageShown: true
    });
}

// Render the child component and set the action property with the handler as value
render() {
    return <Child action={this.handler} />
}}
类父级扩展React.Component{
建造师(道具){
超级(道具)
//将此上下文绑定到处理程序函数
this.handler=this.handler.bind(this);
//设定一些状态
此.state={
消息显示:false
};
}
//此方法将被发送到子组件
处理程序(参数1){
console.log(param1);
这是我的国家({
消息显示:正确
});
}
//渲染
class Parent extends React.Component {
constructor(props) {
    super(props)

    // Bind the this context to the handler function
    this.handler = this.handler.bind(this);

    // Set some state
    this.state = {
        messageShown: false
    };
}

// This method will be sent to the child component
handler(param1) {
console.log(param1);
    this.setState({
        messageShown: true
    });
}

// Render the child component and set the action property with the handler as value
render() {
    return <Child action={this.handler} />
}}
class Child extends React.Component {
render() {
    return (
        <div>
            {/* The button will execute the handler function set by the parent component */}
            <Button onClick={this.props.action.bind(this,param1)} />
        </div>
    )
} }
<Footer 
  action={()=>this.setState({showChart: true})}
/>

<footer className="row">
    <button type="button" onClick={this.props.action}>Edit</button>
  {console.log(this.props)}
</footer>

Try this example to write inline setState, it avoids creating another function.
import React, { Component } from 'react';
import ChildComponent from './ChildComponent';

class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.state = {
      count: '',
    };
  }

  handleInputChange(e) {
    const { value, name } = e.target;
    this.setState({ [name]: value });
  }

  render() {
    const { count } = this.state;
    return (
      <ChildComponent count={count} handleInputChange={this.handleInputChange} />
    );
  }
}
import React from 'react';
import { func, number } from 'prop-types';

const ChildComponent = ({ handleInputChange, count }) => (
  <input onChange={handleInputChange} value={count} name="count" />
);

ChildComponent.propTypes = {
  count: number,
  handleInputChange: func.isRequired,
};

ChildComponent.defaultProps = {
  count: 0,
};

export default ChildComponent;
 class Parent extends React.Component {
  constructor(props) {
    super(props)
    // without bind, replaced by arrow func below
  }

  handler = (val) => {
    this.setState({
      someVar: val
    })
  }

  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <Button onClick = {() => this.props.handler('the passing value')}/ >
  }
}
class Parent extends React.Component {
  handler = (Value_Passed_From_SubChild) => {
    console.log("Parent got triggered when a grandchild button was clicked");
    console.log("Parent->Child->SubChild");
    console.log(Value_Passed_From_SubChild);
  }
  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <SubChild handler = {this.props.handler}/ >
  }
}

class SubChild extends React.Component {
  constructor(props){
   super(props);
   this.state = {
      somethingImp : [1,2,3,4]
   }
  }
  render() {
     return <button onClick = {this.props.handler(this.state.somethingImp)}>Clickme<button/>
  }
}
React.render(<Parent />,document.getElementById('app'));

 HTML
 ----
 <div id="app"></div>
class Parent extends React.Component {

  constructor() {
    super();
    this.state = {
      someVar: value
    }
  }

  handleChange = (someValue) => {
    this.setState({someVar: someValue})
  }

  render() {
    return <Child handler={this.handleChange} />
  }

}

export const Child = ({handler}) => {
  return <Button onClick={handler} />
}
handleChange = (someValue) => {
  this.setState({someVar: someValue})
}
class ParentComponent extends React.Component {
    constructor(props){
        super(props);
        this.state = {
           page: 0
        }
    }

    handler(val){
        console.log(val) // 1
    }

    render(){
        return (
            <ChildComponent onChange={this.handler} />
        )
    }
}


class ChildComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
             page: 1
        };
    }

    someMethod = (page) => {
        this.setState({ page: page });
        this.props.onChange(page)
    }

    render() {
        return (
            <Button
                onClick={() => this.someMethod()}
            > Click
        </Button>
      )
   }
}
props = {
    onChange: this.handler
}
<Component5 onSomethingHappenedIn5={this.props.doSomethingAbout5} />
type ParentProps = {}
type ParentState = { someValue: number }
class Parent extends React.Component<ParentProps, ParentState> {
    constructor(props: ParentProps) {
        super(props)
        this.state = { someValue: 0 }

        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(value: number) {
        this.setState({...this.state, someValue: value})
    }

    render() {
        return <div>
            <Child changeFunction={this.handleChange} defaultValue={this.state.someValue} />
            <p>Value: {this.state.someValue}</p>
        </div>
    }
}

type ChildProps = { defaultValue: number, changeFunction: (value: number) => void}
type ChildState = { anotherValue: number }
class Child extends React.Component<ChildProps, ChildState> {
    constructor(props: ChildProps) {
        super(props)
        this.state = { anotherValue: this.props.defaultValue }

        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(value: number) {
        this.setState({...this.state, anotherValue: value})
        this.props.changeFunction(value)
    }

    render() {
        return <div>
            <input onChange={event => this.handleChange(Number(event.target.value))} type='number' value={this.state.anotherValue}/>
        </div>
    }
}
class Parent extends React.Component{
    state = { term : ''}

     onInputChange = (event) => {
         this.setState({term: event.target.value});
     }

     onFormSubmit = (event) => {
         event.preventDefault();
         this.props.onFormSubmit(this.state.term);
     }

     render(){
         return (
             <Child onInputChange={this.onInputChange} onFormSubmit=
                {this.onFormSubmit} />
         )
     }
}


class Child extends React.Component{

     render(){
         return (
             <div className="search-bar ui segment">
                 <form className="ui form" onSubmit={this.props.onFormSubmit}>
                     <div class="field">
                         <label>Search Video</label>
                         <input type="text" value={this.state.term} onChange=
                             {this.props.onInputChange} />
                     </div>
                 </form>
             </div>
         )
     }
}
import React, {useState} from 'react';

const ParentComponent = () => {
  const[state, setState]=useState('');
  
  return(
    <ChildConmponent stateChanger={setState} />
  )
}


const ChildConmponent = ({stateChanger, ...rest}) => {
  return(
    <button onClick={() => stateChanger('New data')}></button>
  )
}