jsx안에서 for문과 if문을 사용하는것이 매우 힘들다.

그래서 map, reduce같은 배열의 메서드를 사용하는데 이번에는 반응속도 게임을 만들어보면서 평균 시간을 구할 때 reduce를 사용해보자.

 

renderAverage = () => {
        const {result} = this.state;
        return result.length === 0 ?
            null:
            <div>평균 시간{this.state.result.reduce((a,c)=>a+c) / this.state.result.length }ms</div>
}

render() {
        const {state, message, result} = this.state;
        return (
            <>
                <div
                    id="screen"
                    className={state}
                    onClick={this.onClickScreen}
                >
                    {message}
                </div>
                {this.renderAverage()}
            </>
        );
    }

보통 JSX에서 조건문을 사용할 떄는 삼항연사자를 많이 사용하거나 값A && 값B 이러한 평가식을 많이 사용한다.

해당 예시에서는 삼항연사자를 사용했다.

 

result.length === 0 ? null : <div>{~}</div>

이렇게 하면 result.length가 0이 아닐 경우에만 <div>{~}</div>를 렌더링한다.

1. 클래스 컴포넌트의 render() 함수 안에서 this.setState() 하지않기

this.setState()를 하면 리렌더가 일어나서 redner()함수가 재실행되는데 거기서 this.setState()를 해버리면 무한루프가 되어버려 성능상에 문제가 생긴다.

 

2. props는 부모가 바꿔줘야한다.

하지만 실무에서는 props를 자식에서 바꿔야하는 경우가 생기는데 그때는 state로 만들어서 바꾼다고 한다.  그래야 부모에게 영향이 안간다. (아니 setState하는 것을 부모가 자식에게 넘겨주면 안되나...???) 

import React, {memo, useState} from "react";

const TryHooks = memo(({index, value, test}) => {
    const [result, setResult] = useState(value);

    const onClick = () => {
        setResult('1');
    }
    return (
        <li onClick={onClick}>
            {index}. <b>{result}</b> {test}
        </li>
    )
});
TryHooks.displayName = 'TryHooks'
export default TryHooks;

요런 느낌이다.

프롭스를 바꾸면 안되는 이유가 자식이 프롭스를 바꾸면 부모가 뜻하지 않게 바뀌어버리기 때문이라고 한다...

 

 

[클래스 컴포넌트에서 프롭스를 state로 변경하는 예시]

class Try extends PureComponent {
	
    //프롭스를 state로 만들어준다. (변경하기 위해)
    state = {
    	result: this.props.result,
        try: this.props.try,
    }
	
    render(){
    	...
    }

}

 

3. 컨텍스트

컨텍스트란? 프롭스를 바로 전달해줄 수 있는 프롭스의 진화형

 

예를 들어 A -> B -> C -> D -> E -> F -> G 이런 컴포넌트 구조가 있을 때 A -> ... -> G 로 프롭스를 넘기려고 한다고 하자.

프롭스는 자식에게 밖에 전달하지 못하므로 중간에 B,C,D,E,F를 거쳐서 가야한다. 프롭스를 받는다는 것은 잘못하면 리렌더링이 일어난다는 의미와 같다.

쓸데없이 가지고 있으면 리렌더링이 일어나는 위험이 높아져버린다.

 

바로 전달해주는 방법이 필요한데 그것이 바로 컨텍스트, 리덕스이다. 

React.createRef는 클래스 컴포넌트에서도 함수 컴포넌트의 useRef hooks처럼 사용 할 수 있는 방법이다.

useRef처럼 사용하기 때문에 current도 붙여줘야한다.

 

react에서 dom reference를 가져오는 방법

1. class에서 가져오기

input;
onRefInput = c =>{
    this.input = c;
}

render(){
	...
    <input ref={this.onRefInput} />
    ...
}

 

2. hooks에서 가져오기

import {useRef} = from "react";

const inputRef = useRef(null);

//ref 사용하기
const use = e => {
	inputRef.current.focus();
}

return (
	...
    <input type="text" maxLength={4} ref={inputRef}
    ...
)

 

 

근데 클래스 컴포넌트에서도 함수 컴포넌트처럼 가져오는 방법이 있다.

import React, {Component, createRef} from "react";

createRef를 import한다.

 

/*
onRefInput = c => {
    this.input = c;
}
*/

//위의 코드를 대체한다.
input = createRef();

 

render(){
	return (
    	<input ref={this.input} />
    )
}

이렇게 하면 된다.

 

근데 사용할 때도 hooks와 같이 current를 사용해줘야한다.

this.input.current.focus(); 이렇게. current를 더 써줘야하니까 더 안좋은게 아니냐고 반문할 수도 있지만 hooks와 통일성이 있기 때문에 외울 것이 하나 줄어드는 장점을 가진다.

 

 

+ Recent posts