React官方文档--Lifting State Up

2023-11-20

Lifting State Up

如果,几个组件需要同时影响并且修改同一个数据,我们建议将这个共享状态进行提升,给他们最近的共同祖先。
在这个部分,我们将要创建一个温度计算器来判断水会不会在给定温度下沸腾。
我们将从一个叫做BoilingVerdict的组件开始,这个组件接收celsius温度作为属性,然后打印是否足够让水沸腾。
然后我们创建一个组件叫做Calculator,这个组件渲染一个<input>元素让你输入温度,并且将温度存储在this.state.value中,另外,他渲染了BoilingVerdict元素,通过当前输入的值。

function BoilingVerdict(props) {
    if (props.celsius >= 100) {
        return <p>The water would boil.</p>;
    } else {
        return <p>The water would not boil.</p>;
    }
}

class Calculator extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: ""
        };
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) {
        this.setState({
            value: event.target.value
        });
    }
    render() {
        return (
            <div>
                <label htmlFor="temp">celsius: </label>
                <input type="text" value={this.state.value} name="temp" onChange={this.handleChange}/>
                <br/>
                <BoilingVerdict celsius={this.state.value}/>
            </div>
        );
    }
}

ReactDOM.render(
    <Calculator />,
    document.getElementById("root")
);

添加第二个输入

我们的新的需求是,除了摄氏温度的输入,还添加一个华氏温度的输入,然后这两个保持是异步的。
我们通过拆分一个TempertatureInput组件开始,我们将会添加一个新的scale属性来标记是摄氏还是华氏。

const scaleNames = {
    c: 'Celsius',
    f: 'Fahrenheit'
};
function BoilingVerdict(props) {
  if (props.celsius >= 100) {
    return <p>The water would boil.</p>;
  }
  return <p>The water would not boil.</p>;
}
function toCelsius(fahrenheit) {
    return (fahrenheit - 32) * 5 / 9;
}
function toFahrenheit(celsius) {
    return (celsius * 9 / 5) + 32;
}
function tryConvert(value, convert) {
    const input = parseFloat(value);
    if (Number.isNaN(input)) {
        return '';
    }
    const output = convert(input);
    const rounded = Math.round(output * 1000) / 1000;
    return rounded.toString();
}
class TemperatureInput extends React.Component {
    constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.state = {
            value: ''
        }
    }
    //这里封装了父组件的onChange函数
    handleChange(event) {
        this.props.onChange(event.target.value);
    }

    render() {
        const value = this.props.value;
        const scale = this.props.scale;
        return (
            <fieldset>
                <legend>Enter Temperature in {scaleNames[scale]}: </legend>
                <input type="text" value={value} onChange={this.handleChange}/>
            </fieldset>
        );
    }
}

class Calculator extends React.Component {
    constructor(props) {
        super(props);
        this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
        this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
        this.state = {
            value: '',
            scale: 'c'
        };
    }

    handleCelsiusChange(value) {
        console.log(value);
        this.setState({
            scale: 'c',
            value
        });
    }

    handleFahrenheitChange(value) {
        console.log(value);
        this.setState({
            scale: 'f',
            value
        });
    }

    render() {
        const scale = this.state.scale;
        const value = this.state.value;
        const celsius = scale === 'f' ? tryConvert(value, toCelsius) : value;
        const fahrenheit = scale === 'c' ? tryConvert(value, toFahrenheit) : value;
        return (
            <div>
                //这个组件的onChange函数是经过TemperatureInput封装的
                <TemperatureInput scale="c" value={celsius} onChange={this.handleCelsiusChange} />
                <TemperatureInput scale="f" value={fahrenheit} onChange={this.handleFahrenheitChange} />
                <BoilingVerdict celsius={parseFloat(celsius)} />
            </div>
        );
    }
}

ReactDOM.render(
    <Calculator />,
    document.getElementById("root")
);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React官方文档--Lifting State Up 的相关文章

  • 如何通过 JavaScript 访问屏幕显示的 DPI 设置? [复制]

    这个问题在这里已经有答案了 有没有办法在 Javascript 函数中访问屏幕显示的 DPI 设置 我试图在页面上放置一个 HTML 面板 当用户的 DPI 设置为大 120 时 它会丢失该位置 我需要知道 DPI 是多少 以便我可以相应地
  • Safari 中的日期无效

    alert new Date 2010 11 29 chrome ff 对此没有问题 但 safari 会喊 无效日期 为什么 编辑 好的 根据下面的评论 我使用了字符串解析并尝试了这个 alert new Date 11 29 2010
  • Canvas 动画在 FireFox 中卡顿,但在 Chrome 中完美

    我最近开始做一些 HTML5 Canvas 的东西 并且很高兴地开展我的业务 在 Chrome 中测试东西 直到我决定尝试我在 Firefox 中所做的事情 效果不太好 这是我正在做的事情的一个简单的例子 设置基本的 requestAnim
  • 带层的 NodeJS Lambda - 如何防止打字稿在构建中包含层

    我正在用打字稿编写一个 NodeJs lambda 函数 它依赖于 Lambda 层才能工作 我在项目文件夹中创建了一个包含示例层的目录 然后使用 tsconfig 文件中的路径选项以便在本地测试它 然而 这工作得很好 当我构建代码来编译
  • jquery是如何实现$(document).ready()的?

    jquery是如何实现的 document ready 当然我可以阅读代码 但我正在寻找这个概念 概念 jQuery ready http api jquery com ready 虽然 JavaScript 提供了在渲染页面时执行代码的
  • 查找椭圆或贝塞尔曲线上的等距点

    目前我正在编写 JavaScript 代码 将对象放置在屏幕上的椭圆上 我试图找到能够解决这个问题之一的算法 椭圆将是完美的 但如果它太昂贵 贝塞尔曲线也可以 抱歉 但不幸的是我的数学不允许我使用我找到的答案 https mathoverf
  • Fabric JS ClipPath:裁剪后如何使图像适合画布?

    我使用 FabricJS 和 ClipPath 属性实现了图像裁剪 问题是如何使裁剪后的图像适合画布 我希望裁剪后的图像填充画布区域 但不知道是否可以使用 Fabric js 来完成 因此 我希望用户单击 裁剪 按钮后图像的选定部分适合画布
  • 在 Twitter Bootstrap 轮播中显示下一张和上一张图像

    我正在寻找一种在 Twitter Bootstrap 轮播中显示下一张和上一张幻灯片图像的方法 默认情况下 它只显示当前图像 如果我删除 display none css 属性 则轮播中的每个项目都在彼此下方 我尝试过使用 CSS 但还没有
  • 使用 jQuery 的 $.get 和 GMail API 时出现 401(未经授权)错误

    我试图在用户使用 javascript 使用 G API 登录后运行 jQuery 的 get 但在浏览器控制台中收到 401 未经授权 错误 这是我请求的 url 的格式 https www googleapis com gmail v1
  • Safari 不设置 cookie,但 Chrome 和 Firefox 会设置

    我正在将请求从本地主机发送到第三方服务器以使用 REST API 获取数据 后端使用cookies JSESSIONID 来了解是否发送数据 在 Chrome 中一切正常 我可以在 Chrome 浏览器的 应用程序 选项卡中看到 Cooki
  • ReactJS React-pdf 错误“无法加载 PDF 文件。”经过一些尝试

    我创建了一个 React js 应用程序create react app我正在尝试react pdf查看 pdf 我遇到的问题是我的代码有时有效 有时无效 当我第一次加载应用程序时 pdf 总是加载得很好 但如果我访问网站上的其他链接 ur
  • JavaScript 中的对象具有属性深度检查

    假设我们有这个 JavaScript 对象 var object innerObject deepObject value Here am I 我们如何检查是否value财产存在吗 我只能看到两种方法 第一 if object object
  • 带有 Form 和 $setPristine 的 Angular 1.5 组件

    我正在尝试在 Angular 1 5 的组件中使用表单 我的表单可以正常工作 因为我有模型绑定并且可以在提交时获取数据 所以我已经完成了 90 的目标 缺少的是能够使用 setPristine 正确重置表单 我尝试了几种方法 第一种方法是将
  • Javascript 函数无法返回元素

    所以我正在与手动表 http handsontable com 目前项目的 jQuery 插件 我已经编写了一些自定义函数来使用它 我目前遇到问题的函数是我编写的一个函数 用于返回当前选定的单元格 当用户仅选择一个而不是多个时 是的 已检查
  • jquery 克隆组合框无法运行

    我有下表 当我按下第一个按钮时 我调用 jquery 来克隆第一行并添加新行 table class table table striped table bordered bootstrap datatable style font siz
  • 正则表达式 - 匹配包含 2 个或更多 2 个字母元音序列的单词

    我想知道如何匹配包含 2 个或更多 2 个字母元音序列的单词 使用 javascript 版本的正则表达式 例如 visionproof steamier preequip 我现在正在学习正则表达式 这就是我到目前为止所拥有的 它只匹配包含
  • 如何访问使用 YUI 检查的单选按钮的值?

    我有以下单选按钮结构 div div
  • 按位置获取元素?

    我正在研究 SVG 脚本 有 getElementById 或 getElementsByTagName 但我找不到任何方法来按位置获取元素 比如获取位置为x 10 y 10的元素 有什么办法可以实现这个目标吗 var yourElemen
  • 每 x 秒对 SVG 元素进行动画处理

    介绍 我了解一些基本的动画技术SVG两者同时使用Javascript和 DOM
  • 预期的 catch() 或返回(promise/catch-or-return)

    我是 JavaScript 新手 这是我在 javascript 中第一个在 firebase 上部署函数的函数 得到这个错误 eslint Unexpected function expression prefer arrow callb

随机推荐