Как передать функцию и данные из класса компонента в класс без состояния в React Native? - PullRequest
1 голос
/ 27 мая 2020

Я работаю с встроенным реагентом и хочу передать функцию и некоторые данные из класса Component другому классу Stateless , но я не смог передать функцию и часть данных.

Здесь вы можете увидеть мой класс Component:

class Classroom extends Component {

    constructor(props, context) {
        super(props, context);



    };

    state = {
        isLightOn: false,
        title : "Turn light on "
    }

   onPress() {
       this.setState({isLightOn: !this.state.isLightOn})
       console.log(this.state.isLightOn)
       this.setState({title:this.state.isLightOn===false ?"Turn light off":"Turn light on"})

   }

    render() {
        return (
            <View style={styles.blue}>

                <LightBulb  isLightOn={this.state.isLightOn}> </LightBulb>
                <LightButton onPress={this.onPress} isLightOn={this.state.isLightOn} title={this.state.title} > </LightButton>


            </View>
        );
    }


}

Во-первых, я хочу передать isLightOn и title данные в мой класс LightButton (что означает для моего класса без состояния). После этого я хочу использовать функцию onPress внутри моего класса Stateless, но не могу использовать. Я беру эту ошибку:

Превышена максимальная глубина обновления. Это может произойти, когда компонент многократно вызывает setState внутри componentWillUpdate или componentDidUpdate. React ограничивает количество вложенных обновлений, чтобы предотвратить бесконечные циклы.

Я также LightButton onPress = {this.onPress} удаляю круглые скобки, но все равно ошибаюсь.

Вот мой мой Stateless class

const LightButton = ({onPress,isLightOn,title}) => (


        <View style={styles.red}>


            <Button
                title= {title}
                onPress={() => {}

                }
            />
        </View>
)

Я хочу использовать функцию onPress и данные внутри этого класса. В результате, как я могу передать функцию и данные этому классу?

Ответы [ 3 ]

1 голос
/ 27 мая 2020

Основная проблема здесь в том, что вам нужно объявить onPress с помощью стрелочной функции или привязать его к значению this компонента в конструкторе. В противном случае у него не было бы доступа к правильному значению this. В остальном, способ передачи пропсов в компоненты совершенно нормален.

Я также объединил ваши два вызова set state в onPress в один, поскольку это проще.

В LightButton я настройте его так, чтобы передать функцию onPress на кнопку:

const LightButton = ({ onPress, isLightOn, title }) => (
  <div style={{backgroundColor:'red'}}>
    <Button title={title} onPress={onPress} />
  </div>
);

(я настроил его с помощью реакции, но рассматриваемые проблемы больше относятся к проблеме JS, чем к React / ReactNative один, так что совет должен оставаться в силе :))

const { Component } = React;
const View = 'div';
const Button = (({title,onPress})=><button onClick={onPress}>{title}</button>);

const LightBulb = ({ isLightOn }) => {
  return <div className={'LightBulb' + (isLightOn ? ' on' : '')} />;
};

const LightButton = ({ onPress, isLightOn, title }) => (
  <div style={{backgroundColor:'red'}}>
    <Button title={title} onPress={onPress} />
  </div>
);
class Classroom extends Component {
  state = {
    isLightOn: false,
    title: 'Turn light on ',
  };

  onPress=()=> {
    console.log(this.state.isLightOn);
    this.setState({
      title:
        this.state.isLightOn === false ? 'Turn light off' : 'Turn light on',
        isLightOn: !this.state.isLightOn
    });
  }

  render() {
    return (
      <div style={{backgroundColor:'blue'}}>
        <LightBulb isLightOn={this.state.isLightOn}> </LightBulb>
        <LightButton
          onPress={this.onPress}
          isLightOn={this.state.isLightOn}
          title={this.state.title}
        >Button</LightButton>
      </div>
    );
  }
}

ReactDOM.render(<Classroom />, document.querySelector('#root'));
.LightBulb {
  height: 50px;
  width: 50px;
  border-radius: 50px;
  background-color: black;
}
.LightBulb.on {
  background-color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"/>
0 голосов
/ 27 мая 2020

Вы можете назначить его как


const LightButton = ({onPress,isLightOn,title}) => (
  ...
  onPress={onPress}
  ...

или с помощью функции стрелки, если вам нужно передать аргумент внутри


onPress={()=>onPress(someArg)}

обратите внимание, что вы либо вообще не ставите (), либо дважды () => func(), чтобы не запускать функцию, пока она просто загружается и не нажимается.

не связано напрямую с вашей проблемой, но с чем-то, с чем вы сталкиваетесь находится внутри onPress, сделав так


 this.setState({isLightOn: !this.state.isLightOn})
 console.log(this.state.isLightOn)
 this.setState({title:this.state.isLightOn===false ?"Turn light off":"Turn light on"})

setState это асинхронный c вызов, и поэтому второе использование setState не гарантирует ссылки на состояние как вы ожидаете, используйте setState({ ... }, () => callback()) или все в одной строке и в соответствии с предыдущим состоянием


 this.setState({isLightOn: !this.state.isLightOn, title: !this.state.isLightOn===false ?"Turn light off":"Turn light on"})
0 голосов
/ 27 мая 2020
  1. Первое, что вы сделали неправильно, - это создание экземпляра состояния! вам нужно создать экземпляр своего состояния в блоке constructor, например:
constructor(props, context) {
  super(props, context);
  this.state = { counter: 0 };
}

onPress() вы используете это для своей функции, которая не рекомендуется в react native или любом другом языке, это специальные функции и методы React Native.

Для передачи параметр или вызов функции лучше использовать эти шаблоны ====>

onPress={() => urFunction()} со скобками или

onPress={urFunction} без скобок

Внесите изменения, надеюсь, это поможет <3 </p>

...