我想将这两种状态作为Settings组件中的getSettings方法的结果传递给Add组件。有没有办法将方法复制到其他组件?
谢谢
设置组件
export class Settings extends Component {
constructor(props) {
super(props);
this.state = {
languages: [],
currencies: []
};
}
getSettings() {
fetch('/settings', {
method: 'get',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then( ... )
.then(json => {
this.setState({
currencies: json.currencies,
languages: json.languages
});
})
}
}
添加组件
export class Add extends Component {
displayName = Add.name
constructor(props) {
super(props);
this.state = {
languages: [],
currencies: []
};
}
答案 0 :(得分:5)
我可以想到两种在Settings
中共享状态的方式。
您只需将状态传递到this.props.children
或this.props.render
。
class Settings extends Component {
state = {
languages: [],
currencies: []
};
getSettings = () => {
// fetch('/settings', {
// method: 'get',
// headers: {
// 'Accept': 'application/json',
// 'Content-Type': 'application/json'
// }
// })
// .then( ... )
// .then(json => {
// this.setState({
// currencies: json.currencies,
// languages: json.languages
// });
// })
this.setState({
currencies: ["Dollar", "Euro", "Won"],
languages: ["English", "French", "Korean"]
});
};
componentDidMount() {
this.getSettings();
}
render() {
return <div>{this.props.children(this.state)}</div>;
}
}
并像这样使用它。
const renderComponents = (currencies, languages) => {
const currencyItems = currencies.map(currency => (
<li key={currency}>{currency}</li>
));
const languageItems = languages.map(language => (
<li key={language}>{language}</li>
));
return (
<div>
<h3>currencies</h3>
<ul>{currencyItems}</ul>
<hr />
<h3>languages</h3>
<ul>{languageItems}</ul>
</div>
);
};
const AppChildAsFunction = () => (
<div>
<h2>Using Child as Function</h2>
<Settings>
{({ currencies, languages }) => renderComponents(currencies, languages)}
</Settings>
</div>
);
创建和导出新的设置提供程序以及使用者
SettingsContext.js
import React, { Component } from "react";
const defaultValue = {
currencies: ["Dollar", "Euro", "Won"],
languages: ["English", "French", "Korean"]
};
const { Provider, Consumer: SettingsConsumer } = React.createContext(
defaultValue
);
class SettingsProvider extends Component {
state = {
languages: [],
currencies: []
};
render() {
return <Provider value={this.state}>{this.props.children}</Provider>;
}
}
export { SettingsProvider, SettingsConsumer };
用法也差不多
App.js
import { SettingsProvider, SettingsConsumer } from "./SettingsContext";
...
const AppWithContext = () => (
<div>
<h2>Using Context API</h2>
<SettingsConsumer>
{({ currencies, languages }) => renderComponents(currencies, languages)}
</SettingsConsumer>
</div>
);
您可以选择适合自己口味的任何一种。
答案 1 :(得分:4)
高阶分量对于这种情况很有用。首先,您创建方法withSetting
。
export const withSetting = (Component) => class extends Component {
constructor(props) {
super(props);
this.state = {
languages: [],
currencies: []
};
}
getSettings() {
fetch('/settings', {
method: 'get',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then( ...)
.then(json => {
this.setState({
currencies: json.currencies,
languages: json.languages
});
})
}
render() {
return <Component getSetting={this.getSetting} {...this.state} />
}
}
在Add
组件中。您可以致电this.props.getSetting
或使用this.props. languages
和this.props. currencies
import {withGetSetting} from './withGetSetting'
class Add extends React.Component {...}
export default withSetting(Add)
处了解有关HOC的信息。
答案 2 :(得分:3)
请原谅我慷慨激昂的恳求,但出于对所有神圣事物的热爱,请不要使用高阶组件抽象,渲染道具等。这是一个简单的问题,值得一个简单的解决方案。不需要魔术。不需要深奥的React知识。
恭喜,您现在拥有一个可重用且可独立测试的功能,任何组件(或与此相关的任何其他组件)都可以根据需要使用。
const getSettings = component => () => {
// Do your fetch here, and in your last
// .then(), just use 'component.setState'
// instead of 'this.setState'
// Simulate async
setTimeout(() => {
component.setState({
name: component.name,
currencies: "whatever",
languages: "yep"
});
}, 1000);
};
export default getSettings;
就这么简单。
请参见https://codesandbox.io/s/mjmpw5k08y
事后看来,您可能会接受回调函数而不是组件,或返回诺言。这些中的任何一个都将使其与React组件的耦合减少。未经测试的代码如下...
const getSettings = callback => {
// Simulate async
setTimeout(() => {
callback({
name: component.name,
currencies: "whatever",
languages: "yep"
});
}, 1000);
};
用法
getSettings(this.setState.bind(this));
const getSettings = () => window.fetch
.then(res => res.json());
用法
getSettings().then(this.setState.bind(this));
答案 3 :(得分:1)
您可以尝试以下类似方法,不确定如何渲染<Add>
组件的方式和位置:
export class Settings extends Component {
constructor(props) {
super(props);
this.state = {
languages: [],
currencies: []
};
}
getSettings() {
return fetch('/settings', {
method: 'get',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(...)
.then(json => {
this.setState({
currencies: json.currencies,
languages: json.languages
});
})
}
render() {
return (
{ this.getSettings() && <Add { ...this.state}/> }
);
}
}
在您的<Add>
组件中,只需使用其渲染方法从props
中读取即可。