Реагировать: создавать соединения между компонентами

#reactjs #typescript #react-native #react-tsx

#reactjs ( реакция ) #машинописный текст #реагировать-собственный #реагировать-tsx

Вопрос:

Я новичок в React JS. Возиться, чтобы получить прослушиватели событий VanJS.

Для макета я решаю хранить такие вещи, как a panel, a button как отдельный компонент.

Теперь у меня есть компонент Movie и другой компонент Button , как я могу вызвать изменение состояния фильма с помощью Button.onclick()?.

Другими словами, как изменить компонент по событию, происходящему на другом компоненте?

Перед публикацией я прочитал:

но тонны методов, за которыми следует, действительно смутили меня.

  • useState
  • componentWillMount : непосредственно перед начальной визуализацией
  • componentDidMount : сразу после первоначального рендеринга
  • componentWillReceiveProps : когда компонент получает новые реквизиты
  • shouldComponentUpdate : перед рендерингом, после получения новых реквизитов или состояния
  • componentWillUpdate : перед рендерингом, после получения новых реквизитов или состояния.
  • componentDidUpdate : после обновления компонента сбрасываются в DOM
  • componentWillUnmount : непосредственно перед удалением компонента из DOM

Ниже приведена демонстрация, которая содержит Movie карточку и Button , когда нажимается кнопка, я хочу, чтобы цвет фона видеозаписи изменился

Песочница для кода React TypeScript

код:

 import * as React from "react";
import "./styles.css";
import styled from 'styled-components';

function CSSPropertiesToComponent(dict:React.CSSProperties){
  let str = '';
  for(const [key, value] of Object.entries(dict)){
      let clo = '';
      key.split('').forEach(lt=>{
          if(lt.toUpperCase() === lt){
              clo  = '-'   lt.toLowerCase();
          }else{
              clo  = <
          }
      });
      str  = clo   ':'   value   ';';
  }
  return str;
}

class Movie extends React.Component<any, any>{
  public static style:React.CSSProperties|object = {
      width: "300px",
      height: "120px",
      display: "flex",
      justifyContent: "space-around",
      alignItems: "center",
      borderRadius: "20px",
      filter: "drop-shadow(0px 1px 3px #6d6d6d)",
      WebkitFilter: "drop-shadow(3px 3px 3px #6d6d6d)",
      backgroundColor: '#' Math.floor(Math.random()*16777215).toString(16),
      fontSize: '2.5rem',
      margin: '20px',
      color: '#fff',
  }

  props:React.ComponentProps<any>;
  state:React.ComponentState;

  constructor(props:any) {
      super(props);
      this.props = props;
      this.state = {style: Object.assign({}, Movie.style)}
      this.changeColor = this.changeColor.bind(this);
  }

  changeColor():void{
      this.setState({style: Object.assign({}, Movie.style, {backgroundColor: '#' Math.floor(Math.random()*16777215).toString(16)})});
  }

  render():JSX.Element{
      let StyledMovie = styled.div`
          ${CSSPropertiesToComponent(Movie.style)}
      `;

      return (
          <>
              <StyledMovie>{this.props.title}</StyledMovie>
          </>
      )
  }
}

export default function App() {
  let MV = new Movie({title: 'the Avengers'});
    return (
        <>
            {MV.render()}
            <button onClick={MV.changeColor}>Change Color</button>
        </>
    )
}
  

Однако при нажатии на кнопку «Изменить цвет» это не работает и показывает предупреждение:

 Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the Movie component.
  

если кто-нибудь предложит какое-то предложение, я буду очень рад.

Комментарии:

1. Это не дает наилучшего ответа на ваш вопрос, но показывает очень простой пример использования функциональных компонентов, передающих данные от родителя к дочернему элементу. https://stackblitz.com/edit/react-tswfof

Ответ №1:

 let MV = new Movie({title: 'the Avengers'});
    return (
        <>
            {MV.render()}
            <button onClick={MV.changeColor}>Change Color</button>
        </>
    )
  

Должно выглядеть так (с использованием jsx или tsx):

 
onChangeColor(color) {
  setState({color: color}); // state won't be in Movie component !
}

// use React.Fragment if you don't want an additional div
return (
  <div>
    <Movie title={'the Avengers'} />
    <button onClick={onChangeColor}>Change Color</button>
  <div/>
)
  

Также на class Movie extends React.Component<any, any> вы настраиваете оба общих параметра на любой, первый — это тип «реквизита» компонента (входные данные и обратные вызовы), а второй — тип «состояния» компонента.

 
interface MovieProps {
  // ...
}

interface MovieState {
  // ...
}

class Movie extends React.Component<MovieProps, MovieState> { }
  

Как уже было сказано, глядя на ваш код, вам нужно сохранить состояние вне компонента Movie, возможно, вы захотите сохранить App компонент в чистоте и создать другой компонент для переноса Movie и button , который будет отвечать за взаимодействие между обоими.

Об этом коде можно сказать гораздо больше, но я не могу охватить все, я рекомендую вам следовать руководству, чтобы получить более глубокие основы React.