Скажем, у меня есть родительский компонент.
Parent.js
class Parent extends React.Component {
someMethod () {
LoadDataforChild();
}
render() {
return (
<div>
<Child someMethod = {this.someMethod}/>
</div>
);
}
}
export default Parent;
Child.js (Ребенок - это чистый компонент)
class Child extends React.Component {
componentWillMount() {
this.props.someMethod();
}
render() {
return (
<div>
Hello child
</div>
);
}
}
Я совершенно не знаком с антипаттернами в реакции. Я вызвал родительский метод в Child (чистый компонент). Это антипаттерн? А что такое антипаттерн с точки зрения родительских и дочерних компонентов?
Прошу прощения, поправьте меня, если я ошибаюсь.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В целом антипаттернов не так много, как есть определенный вариант использования для получения данных в родительском элементе - подумайте о нескольких дочерних элементах и т. Д. Но обычно это делается с помощью обратного вызова, например, когда пользователь нажимает кнопку, а не при монтировании. .
В вашем примере было бы разумнее передавать данные непосредственно дочернему элементу в качестве опоры и обрабатывать загрузку данных в родительском событии монтирования.
Обратите внимание, вам, вероятно, следует избегать использования componentWillMount(), поскольку это антипаттерн. Вместо этого используйте componentDidMount(). Прочтите здесь
Распространяя ваш вопрос на анти-шаблоны в reactjs, я хотел бы ответить широко, поскольку я могу основываться на off.docs, статьях и на собственном опыте:
//REDUX REDUCER
const initialState = {
isHOCOpened: false,
child: null
}
export default reducer = (state = initialState, {type, content}) => {
switch (type) {
case ('openHOC'): {
const updatedState = {...state};
updatedState.isHOCOpened = true;
updatedState.child = content;
return {
...state, ...updatedState
}
...
}
//PARENT COMPONENT
...some other imports;
import ChildElement from './ChildElement';
export default class ParentElement extends Component {
...some code...
render() {
const { openHOC, HOCcontent } = this.props;
return (
<div onClick = {()=>this.openHOC(<ChildElements/>)}>
<HOCElement/>
</div>
}
//HIGHER ORDER COMPONENT
export default const HOC = ({isHOCOpened, child}) => {
...some code...
return (
<div>
{isOpened && {children}}
</div>
)
}
Рекомендуемый способ
...some other imports;
import ChildElement from './ChildElement';
export default class ParentElement extends Component {
state = {
isHOCOpened: false,
}
openHOC = () => this.setState({openHOC: true});
render() {
return (
<div onClick = {this.openHOC}>
{isOpened && <HOCElement/><ChildElement/></HOCElement>}
</div>
}
}
...
export default const HOC = ({children}) => {
...some stuff...
return (
<div>{children}</div>
)
Организуйте логику своего приложения, избегая хранения компонентов в состоянии / магазине;
onClick = {() => {
//some code
this.setState({isOpened: true})
}
Лучше уберите это событие и сохраните его, как в предыдущем примере:
openHOC = () => {
//some code
return this.setState({openHOC: true})
};
render() {
return (
<div onClick = {this.openHOC}>
{isOpened && <HOCElement/><ChildElement/></HOCElement>}
</div>
}
Это влияет на производительность, поскольку создает функцию каждый раз, но это затрагивает общее понимание JS, только ReactJS. Прочтите статью для более подробного обсуждения это .;
class App extends Component {
constructor(props) {
super(props);
this.state = {
name: ''
};
}
updateValue(evt) {
this.setState({
name: evt.target.value
});
}
render() {
return (
<form>
<input onChange = {this.updateValue.bind(this)} value = {this.state.name} />
</form>
)
}
}
вместо этого свяжите все вары в функции конструктора:
class App extends Component {
constructor(props) {
super(props);
this.state = {
name: ''
};
this.updateValue = this.updateValue.bind(this);
}
<ul>
{liArray.map( (e,i) => <li key = {i}>{e.text}</li>}
</ul>
Это не совсем антипаттерн, а прямой ошибочный код и неожиданные результаты. Поскольку это много раз было написано в вне документов, React использует ключи для отслеживания изменений в дереве DOM и его перерисовки, поэтому ключи должны быть уникальными, несмотря на то, что индексы изменяют положение его массива;
Поместите уникальные реквизиты как идентификаторы или что-то еще {liArray.map(e => <li key = {e.id}>{e.text}</li>}
setState({value: this.state.counter + passedValue})
Перед вызовом setState выполните: updateValue(passedValue) {
const result = this.state.counter + passedValue;
setState({value: result})
}
updateValue(value) {
this.setState({counter: value});
this.addToCounter(1)
}
потому что setState является асинхронным Проверь это Передайте его в качестве второго аргумента в setState, чтобы запустить его, когда компонент получит новое состояние:
updateValue(value) {
this.setState(
{counter: value},
()=>this.addToCounter(1)
)
}
<mycomponent>content</mycomponent>, но это поможет <Mycomponent>content</MyComponent>. То же самое будет с Кнопка и кнопка;Почему редукс? было бы лучше реагировать без использования redux.
@TomSawyer Я попытался осветить более сложные ситуации, но просто отреагировал. Этот вопрос задается, чтобы помочь новичкам избежать серьезных ошибок с самого начала, и я попытался охватить больше, чем просто случай приложения.
В этом случае дочерний компонент не является чистым компонентом, поскольку вы расширяете
React.Component.