#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
: после обновления компонента сбрасываются в DOMcomponentWillUnmount
: непосредственно перед удалением компонента из 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.