상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달할 때 속성값이 사용된다.
가까운 거리는 속성값으로 충분하지만, 그게 아니라면 속성값을 반복적으로 사용해야 한다.
이럴때, contextAPI
로 비교적 쉽게 데이터를 전달할 수 있다!👍🏻
App Component -> Greeting Component
먼저, contextAPI를 사용하지 않을 때의 코드이다.
전달하고...전달하고...
Profile컴포넌트는 username을 사용하지 않고 전달만한다.
class App extends React.Component {
render() {
return (
<div>
<div>위쪽</div>
<Profile username="sohee" />
<div>아래쪽</div>
</div>
);
}
}
function Profile({ username }) {
return (
<div>
<Greeting username={username} />
{/* ... */}
</div>
);
}
function Greeting({ username }) {
return <p>{`${username}님 안녕하세요`}</p>
}
이번엔 ContextAPI를 사용한 예제이다.
createContext의 함수 구조는 아래와 같다.
React.createContext(defaultValue) => {Provider, Consumer}
const UserContext = React.createContext('unknown');
class App extends React.Component {
render() {
return (
<div>
<UserContext.Provider value="sohee">
<div>위쪽</div>
<Profile />
<div>아래쪽</div>
</UserContext.Provider>
</div>
);
}
}
function Profile() {
return (
<div>
<Greeting />
{/* ... */}
</div>
);
}
function Greeting() {
return (
<UserContext.Consumer>
{username => <p>{`${username}님 안녕하세요`}</p>}
</Usercontext.Consumer>
);
}
상위 컴포넌트에서는 Provider를 이용하여 데이터를 전달한다.
하위 컴포넌트에서는 Consumer를 이용하여 데이터를 사용한다.
만약 상위로 올라가면서 Provider를 찾지 못한다면 default값을 사용한다.
redux에서처럼 context data도 원하는 곳에서 변경할 수 있다.
count를 증가시키는 함수를 콘텍스트 데이터에 포함시킨다.
App의 onHello가 콘텍스트 데이터에 포함되므로 App의 onHello를 호출할 수 있다.
const Usercontext = React.createContext({
username: 'unknown',
count: 0,
onHello: () => {},
});
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
username: 'sohee',
count: 0,
onHello: this.onHello,
};
}
onHello = () => {
const { count } = this.state;
this.setState({ count: count + 1 });
};
render() {
return (
<div>
<UserContext.Provider value={this.state}>
<div>위쪽</div>
<Profile />
<div>아래쪽</div>
</UserContext.Provider>
</div>
);
}
}
function Greeting() {
return (
<UserContext.Consumer>
{value => (
<React.Fragment>
<p>`${value.username}`</p>
<p>{`인사 횟수: ${value.count}`</p>
<button onClick={value.onHello}>인사하기</button>
</React.Fragment>
)}
</Usercontext.Consumer>
}
}
React에서 DOM 요소에 직접 접근해야 할 때 ref를 사용한다.
아래 예제를 보면서 이해하자
class TextInput extends React.Component {
textRef = React.createRef();
componentDidMount() {
this.setTextFocus();
}
setTextFocus() {
this.textRef.current.focus();
}
render() {
return (
<div>
<input type="text" ref={this.textRef} />
<button>저장<button>
</div>
);
}
}
createRef
가 반환하는 ref
객체를 이용해 자식요소에 접근한다.
ref
의 current
속성을 이용하여 input
에 focus
를 주었다.
ref속성값은 클래스형 컴포넌트에서만 사용가능하다.
함수형에서는 내부 리액트 요소에 ref속성값을 주는 식으로 사용한다.
하지만 이 방법은 내부 구조를 외부에서 알아야 하므로 좋은 방법은 아니다.
function TextInput({ textRef }) {
return (
<div>
<input type="text" ref={textRef} />
</div>
);
}
class Form extends React.Component {
textRef = React.createRef();
componentDiMount() {
this.setTextFocus();
}
setTextFocus = () => {
this.textRef.current.focus();
};
render() {
return (
<div>
<TextInput textRef={this.textRef} />
<button onClick={this.setTextFocus}>텍스트로 이동</button>
</div>
);
}
}