react使用过程中常见问题
目录
一、减小输入字符数
二、用props.children来引用位于前置标签和后置标签之间的内容
四、JSX属性采用驼峰式的大小写规则(即‘onClick’而非‘onclick’)
八、列表子元素添加key可以提升virtual dom的子级校正(reconciliation)的速度
九、JSX内联样式采用驼峰式大小写规则,以保持和DOM属性一致
十二、window.fetch的浏览器兼容补丁 whatwg-fetch
十三、js ES6新函数的兼容浏览器垫片, babel-polyfill
十四、Redux-Thunk的作用是改造store.dispatch函数,让其可以接收函数进行分发,函数可带上(dispatch,getState)两参数进行传递
十六、FSA(Flux Standard Action)结构的Action
十七、redux-saga的redux-saga/effects常用的指令
二十、redux常用的json格式化处理库normalizr
二十三、Create React App中的代码切割,Code Splitting in Create React App
二十七、报Error: Plugin/Preset files are not allowed to export objects, only functions.错误的解决方案
一、减小输入字符数
代码如下:
- import React, { Component } from 'react';
- class Hello extends Component {
- // ...
- }
二、用props.children来引用位于前置标签和后置标签之间的内容
代码如下:
- import React, { Component } from 'react';
- import { render } from 'react-dom';
- // Parent Component
- class GroceryList extends Component {
- render() {
- return (
- <ul>
- <ListItem quantity = "1" > Bread </ListItem>
- <ListItem quantity = "6" > Eggs </ListItem>
- <ListItem quantity = "2" > Milk </ListItem>
- </ul>
- );
- }
- }
- // Child Component
- class ListItem extends Component {
- render() {
- return (<li> {this.props.quantity}× {this.props.children} </li>);
- }
- }
- render(<GroceryList /> , document.getElementById('root'));
三、创建组件两条主要的途径
从上而下或者从下而上,尽量让app.js保持简单,只包含数据(数据来自于API)并只渲染出一个KanbanBoard组件
- import React from 'react';
- import { render } from 'react-dom';
- import KanbanBoard from './KanbanBoard';
- let cardsList = [
- { id: 1, title: "Read the Book", description: "I should read the whole book", status: "in-progress", tasks: [] }, {
- id: 2,
- title: "Write some code",
- description: "Code along with the samples in the book",
- status: "todo",
- tasks: [
- { id: 1, name: "ContactList Example", done: true },
- { id: 2, name: "Kanban Example", done: false },
- { id: 3, name: "My own experiments", done: false }
- ]
- }
- ];
- render( <KanbanBoard cards = { cardsList } />, document.getElementById('root'));
四、react属性采用驼峰式的大小写规则(即‘onClick’而非‘onclick’)
五、react只能渲染单一个根节点
代码如下:
- return (
- <h1>Hello World</h1>
- ) // 合法
- return (
- <h1>Hello World</h1>
- <h2>Have a nice day</h2>
- ) // 不合法
六、JSX中不方便使用条件语句的解决方法
解决方案一、使用三元表达式
- render(){
- return (
- <div className={condition ? "show":"hide"}>
- Hello JSX
- </div>
- )
- }
- // 或者
- <div>
- {condition?
- <span> Hello JSX </span>
- : null}
- </div>
解决方案二、将条件外置
- render(){
- let className;
- if(condition) {
- className = "show";
- } else {
- className = "hide";
- }
- }
- return (
- <div className={className}>Hello JSX</div>
- )
七、如何在JSX内部渲染HTML标签
方式、1
- var HelloMessge = React.createClass({
- render: <div
- dangerouslySetInnerHTML={{
- __html: '<h3>hahhah</h3>'
- }}>
- </div>
- })
方式、2
- destroy() {
- if (this._el) {
- this._el.querySelector('.dialog__mask').classList.add('maskFadeOut')
- this._el.querySelector('.dialog__wrapper').classList.add('wrapperFadeOutUp')
- setTimeout(()=>{
- ReactDOM.unmountComponentAtNode(this._el)
- document.body.removeChild(this._el)
- this._el = null
- }, 150)
- }
- }
- open() {
- this._el = document.createElement('div')
- document.body.appendChild(this._el)
- ReactDOM.unstable_renderSubtreeIntoContainer(
- this,
- this.renderDialog(),
- this._el
- ); // 更新组件到传入的 DOM 节点上,完成在组件内实现跨组件的 DOM 操作
- }
- renderDialog() {
- const {
- skin,
- width,
- okBtn,
- okBtnText,
- children,
- cancelBtn,
- cancelBtnText
- } = this.props;
- return (
- <div className="dialog" key="dialog">
- <div className="dialog__mask maskFadeIn dialog_animated" style={{height: (document.body.offsetHeight > window.screen.height ? document.body.offsetHeight : window.screen.height) + 'px'}} />
- <div className={'dialog__wrapper wrapperFadeInDown dialog_animated dialog__wrapper--skin-' + skin} style={{left:'50%', top: (window.screen.height/2 - 100) + 'px', width: width + 'px', marginLeft: (width*(-1)/2) + 'px'}} >
- <div className="dialog__content">
- {children}
- </div>
- {(okBtn || cancelBtn) && (
- <div className="dialog__btns">
- {okBtn && (<button className="dialog__btn dialog__btn--ok" onClick={this.onOk}>{okBtnText}</button>)}
- {cancelBtn && <button className="dialog__btn dialog__btn--cancel" onClick={this.onCancel}>{cancelBtnText}</button>}
- </div>
- )}
- </div>
- </div>
- )
- }
八、列表子元素添加key可以提升virtual dom的子级校正(reconciliation)的速度
九、JSX内联样式采用驼峰式大小写规则,以保持和DOM属性一致
十、高阶组件的主要作用
一:生成包含新功能的新组件
- function hoc(Comp){
- return class NewComponent extends Component {
- // 增加或者修改的功能实现
- extendFunc(){
- }
- render() {
- return (
- <Comp {... this.props} />
- )
- }
- }
- }
- const NewCompent = hoc(Comp);
二:控制props
- const MyContainer = (WrappedComponent) =>
- class extends Component {
- render() {
- const newProps = { text: newText };
- return <WrappedComponent {...this.props} {...newProps} />;
- }
- }
属性转换
- function transProps(transFn){
- return function(Comp){
- return class extends Component {
- render(){
- return <Comp {...transFn(this.props)} />
- }
- }
- }
- }
三:抽象state,高阶组件可以将原组件抽象为展示型组件,分离内部状态
- const MyContainer = (WrappedComponent) =>
- class extends Component {
- constructor(props){
- super(props);
- this.state = {
- name: '',
- };
- this.onNameChange = this.onNameChange.bind(this);
- }
- onNameChange( event ) {
- this.setState(
- name: event.target.value,
- )
- }
- render() {
- const newPros = {
- name: {
- value: this.state.name,
- onChange: this.onNameChange,
- }
- }
- return <WrappedComponent {...this.props} {...newProps} />;
- }
- }
四:封装异步请求
- function hocListWithData({dataLoader, getListFromResultData}) {
- return Com => {
- return class extends Component {
- constructor(props){
- super();
- this.state = {
- resultData: undefined
- }
- }
- componentDidMount(){
- dataLoader()
- .then(data=> this.setState({resultData: data})
- }
- render(){
- return {
- <Comp {...getListFromResultData(this.state.resultData)} {...this.props} />
- }
- }
- }
- }
- }
十一、为什么要用immutable.js?
举个例子,在javascript中
- var a = {a:1};
- var b = a;
- b.a = 2; // => a.a = 2
由上面的例子可以知道,可变数据有时使用起来是会有问题的,在各种数据操作后有可能会使原数据被污染而导致程序出错,才出现immutable.js不可修改数据类型的概念,因此,修改组件状态时,永远不能直接写:
- this.state.arr = newArr; // 或者
- const tempArr = this.state.arr;
- temp.push('hello'); // 此时已经修改了this.state了,不能这样写
- this.state.setState({newArr,tempArr })
可以使用非常侵入式的纯函数如:map、filter、concat或者Object.assign({}, this.state.xxx, {newKey, newValue})来解决这个问题
immutable例子如下:
- import React from 'react'
- import { Map, Set } from 'immutable';
- export default class Clock extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- immutableData: Map({
- date: new Date(),
- name: 'Nelson won\'t change, but time is changing all the time!'
- })
- };
- this.dataSet = Set();
- }
- componentDidMount() {
- this.timerID = setInterval(
- () => this.tick(),
- 10
- );
- let dataSet = Set();
- dataSet = dataSet.add(1);
- dataSet = dataSet.add(2);
- this.dataSet = dataSet;
- }
- componentWillUnmount() {
- clearInterval(this.timerID);
- }
- tick() {
- this.setImmutableState('date',new Date());
- }
- setImmutableState(key, value) {
- this.setState({
- immutableData: this.state.immutableData.set(key, value)
- });
- }
- render() {
- const formatTime = date => {
- let hour = date.getHours();
- let minute = date.getMinutes();
- let second = date.getSeconds();
- let milisecond = Math.floor(date.getMilliseconds() / 10);
- if (hour < 10) {
- hour = '0' + hour;
- }
- if (minute < 10) {
- minute = '0' + minute;
- }
- if (second < 10) {
- second = '0' + second;
- }
- if (milisecond < 10) {
- milisecond = '0' + milisecond;
- }
- return `${hour} : ${minute} : ${second} : ${milisecond}`;
- }
- return (
- <div>
- <h2>现在时间 {formatTime(this.state.immutableData.get('date'))}. Hello {this.state.immutableData.get('name')}. dataSetSize:{this.dataSet.size}</h2>
- </div>
- );
- }
- }
十二、window.fetch的浏览器兼容补丁 whatwg-fetch
- npm install --save whatwg-fetch
- import 'whatwg-fetch';
十三、js ES6新函数的兼容浏览器垫片, babel-polyfill
- npm install --save babel-polyfill
十四、Redux-Thunk的作用是改造store.dispatch函数,让其可以接收函数进行分发,函数可带上(dispatch,getState)两参数进行传递解决异步action传递的问题。
如下面action代码的写法,组件中可以直接写 dispatch(fetchPostsIfNeeded) 分发异步 action:
- export const requestPosts = reddit => ({
- type: REQUEST_POSTS,
- })
- export const receivePosts = (reddit, json) => ({
- type: RECEIVE_POSTS,
- reddit,
- posts: json.data.children.map(child => child.data),
- receivedAt: Date.now()
- })
- const fetchPosts = reddit => dispatch => {
- dispatch(requestPosts(reddit))
- return fetch(`https://www.reddit.com/r/${reddit}.json`)
- .then(response => response.json())
- .then(json => dispatch(receivePosts(reddit, json)))
- }
- const shouldFetchPosts = (state, reddit) => {
- const posts = state.postsByReddit[reddit]
- if (!posts) {
- return true
- }
- if (posts.isFetching) {
- return false
- }
- return posts.didInvalidate
- }
- export const fetchPostsIfNeeded = reddit => (dispatch, getState) => {
- if (shouldFetchPosts(getState(), reddit)) {
- return dispatch(fetchPosts(reddit))
- }
- }
十五、如何编写redux自定义middleware中间件
自定义的middleware一般可以用做处理复杂的异步流,除了redux-thunk, redux-saga这些非常常用的中间件,我们可以自己定义一些中间件:
如处理轮询、多异步串联、修改并重新封装action的值等,
一般的写法如下:
- // 如多异步串联
- const sequenceMiddleware = {dispatch, getState} => next => action => {
- if(!Array.isArray(action)){
- return next(action);
- }
- return action.reduce((result, currAction) => {
- return result.then() => {
- return Array.isArray(currAction) ?
- Promise.all(currAction.map(item => dispatch(item))) :
- dispatch(currAction);
- })
- }, Promise.resolve());
- }
- // 或者这样写
- export default store => next => action => {
- // ...
- }
代码引用自:《深入react技术栈》
十六、FSA(Flux Standard Action)结构的Action
- {
- type: 'ADD_TODO',
- payload: {
- text: 'Do something.'
- }
- }
- // 一个action必须是一个普通的JavaScript对象,有一个type字段
- // 一个action可能有error字段、payload字段、meta字段。
- // 一个action必须不能包含除type、payload、error及meta以外的其他字段。
十七、redux-saga的redux-saga/effects常用的指令
- yield put({ type: 'INCREMENT' }) // put: 分发一个type为'INCREMENT'的action 到 Store
- yield call(delay, 1000) // 不直接执行delay函数,用call便于跟踪及测试
- yield call([obj, obj.method], arg1, arg2, ...) // 如同 obj.method(arg1, arg2 ...)
- yield apply(obj, obj.method, [arg1, arg2, ...]) // call 和 apply 非常适合返回 Promise 结果的函数
- const content = yield cps(readFile, '/path/to/file') // cps 可以用来处理 Node 风格的函数 (例如,fn(...args, callback) 中的 callback 是 (error, result) => () 这样的形式,cps 表示的是延续传递风格(Continuation Passing Style))
- yield* takeEvery('FETCH_REQUESTED', fetchData) // takeEvery 监听并允许多个 fetchData 实例同时启动
- yield* takeLatest('FETCH_REQUESTED', fetchData) // takeLatest 监听并只允许执行一个 fetchData 任务。并且这个任务是最后被启动的那个。 如果之前已经有一个任务在执行,那之前的这个任务会自动被取消
- // 错误处理
- function* fetchProducts() {
- try {
- const products = yield call(Api.fetch, '/products')
- yield put({ type: 'PRODUCTS_RECEIVED', products })
- }
- catch(error) {
- yield put({ type: 'PRODUCTS_REQUEST_FAILED', error })
- }
- }
- // 简单的logger
- export function* watchAndLog() {
- while (true) {
- const action = yield take('*') // 监听所有action
- const state = yield select() // select作用和 redux thunk 中的 getState 相同
- console.log('action', action)
- console.log('state after', state)
- }
- }
- // select内容
- const id = yield select(state => state.id);
- const tokenTask= yield fork(authorize, user, password) // 相比起call来说,fork是无阻塞调用
- yield cancel(tokenTask) // 可取消task
- // 正确写法, effects 将会同步并行执行
- const [users, repos] = yield [
- call(fetch, '/users'),
- call(fetch, '/repos')
- ]
- // 当我们需要 yield 一个包含 effects 的数组, generator 会被阻塞直到所有的 effects 都执行完毕,或者当一个 effect 被拒绝 (就像 Promise.all 的行为)。
- const {posts, timeout} = yield race({
- posts : call(fetchApi, '/posts'),
- timeout : call(delay, 1000)
- }) // race Effect 提供了一个方法,在多个 Effects 之间触发一个竞赛(race)。它会自动取消那些失败的 Effects
- // yield* 对 Sagas 进行排序,可以使用内置的 yield* 操作符来组合多个 Sagas,使得它们保持顺序,如下:
- function* playLevelOne(getState) { /*...*/ }
- function* playLevelTwo(getState) { /*...*/ }
- function* playLevelThree(getState) { /*...*/ }
- function* game(getState) {
- const score1 = yield* playLevelOne(getState)
- put(showScore(score1))
- const score2 = yield* playLevelTwo(getState)
- put(showScore(score2))
- const score3 = yield* playLevelThree(getState)
- put(showScore(score3))
- }
- // 任务的取消
- // 或直接使用 `isCancelError(error)`
- if(error instanceof SagaCancellationException)
- yield put(actions.requestFailure('Sync cancelled!'))
十八、redux使用过程中常用的lodash函数
- _.union([1, 2], [4, 2], [2, 1]); // 字符或者数字数组去重
- // => [1, 2, 4]
- var users = {
- 'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
- };
- var ages = {
- 'data': [{ 'age': 36 }, { 'age': 40 }]
- };
- _.merge(users, ages); // 合并对象数组
- // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
- // using a customizer callback
- var object = {
- 'fruits': ['apple'],
- 'vegetables': ['beet']
- };
- var other = {
- 'fruits': ['banana'],
- 'vegetables': ['carrot']
- };
- _.merge(object, other, function(a, b) { // 按函数合并对象数组
- if (_.isArray(a)) {
- return a.concat(b);
- }
- });
- // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
- _.zip(['fred', 'barney'], [30, 40], [true, false]); // 数组按顺序组合成新数组
- // => [['fred', 30, true], ['barney', 40, false]]
十九、redux常用的驼峰化处理库humps
- humps.camelize('hello_world') // 'helloWorld'
- humps.decamelize('fooBar') // 'foo_bar'
- humps.decamelize('fooBarBaz', { separator: '-' }) // 'foo-bar-baz'
- var object = { attr_one: 'foo', attr_two: 'bar' }
- humps.camelizeKeys(object); // { attrOne: 'foo', attrTwo: 'bar' }
- var array = [{ attr_one: 'foo' }, { attr_one: 'bar' }]
- humps.camelizeKeys(array); // [{ attrOne: 'foo' }, { attrOne: 'bar' }]
二十、redux常用的json格式化处理库normalizr
- // 源数据
- {
- "id": "123",
- "author": {
- "id": "1",
- "name": "Paul"
- },
- "title": "My awesome blog post",
- "comments": [
- {
- "id": "324",
- "commenter": {
- "id": "2",
- "name": "Nicole"
- }
- }
- ]
- }
- // 处理
- import { normalize, schema } from 'normalizr';
- // Define a users schema
- const user = new schema.Entity('users');
- // Define your comments schema
- const comment = new schema.Entity('comments', {
- commenter: user
- });
- // Define your article
- const article = new schema.Entity('articles', {
- author: user,
- comments: [ comment ]
- });
- const normalizedData = normalize(originalData, article);
- // =>
- {
- result: "123",
- entities: {
- "articles": {
- "123": {
- id: "123",
- author: "1",
- title: "My awesome blog post",
- comments: [ "324" ]
- }
- },
- "users": {
- "1": { "id": "1", "name": "Paul" },
- "2": { "id": "2", "name": "Nicole" }
- },
- "comments": {
- "324": { id: "324", "commenter": "2" }
- }
- }
- }
二十一、react中常用到的新的js函数
- const cart = json.carts.find(cart => cart.cartId === id);
- Object.assign({}, obj, obj);
- // reduce
- // map
- // filter ...还有 ... spread函数
二十二、react中如何阻止事件冒泡
- onDelete={(e) => {
- e.stopPropagation();
- e.nativeEvent.stopImmediatePropagation();
- onDelete(todo.id)
- }
- }
二十三、Create React App中的代码切割,Code Splitting in Create React App
参考:Code Splitting in Create React App
二十四、React组件生命周期
参考:React Component Lifecycle(生命周期)和 React组件生命周期小结
二十五、setState注意事项
1、setState是异步的。
2、setState会造成不必要的渲染,新的 state 其实和之前的有可能是一样的。这个问题通常可以通过 shouldComponentUpdate 来解决。也可以用 pure render 或者其他的库赖解决这个问题。
3、setState并不能很有效的管理所有的组件状态
二十六、mobx在ReactJS项目中的运用
引用自:http://blog.csdn.net/u012125579/article/details/69400169
mobx 最最核心的概念只有2个。 @observable 和 @observer ,它们分别对应的是被观察者和观察者。这是大家常见的观察者模式,不过这里使用了,ES7 中的 装饰器。
核心概念2 actions 和 computed values,在 Component 中调用,这样通过 action 的方法,就避免了直接修改 props 的问题。可以通过引入 mobx 定义的严格模式,强制使用 action 来修改状态。mobx 提供了 computed 装饰器,用于获取由基础 state 衍生出来的值
- import React, {Component} from 'react';
- import { render } from 'react-dom';
- import {observable, action, computed,useStrict} from 'mobx';
- import {observer} from 'mobx-react';
- useStrict(true);
- class Store {
- @observable todos = [{ // 被观察者
- title: "todo标题",
- done: false,
- },{
- title: "已经完成 todo 的标题",
- done: true,
- }];
- @action changeTodoTitle({index,title}){
- this.todos[index].title = title
- }
- @computed get unfinishedTodos () {
- return this.todos.filter((todo) => todo.done)
- }
- }
- @observer // 观察者
- class TodoBox extends Component {
- render() {
- console.log('render');
- return (
- <div>
- <ul>
- { /* 把 unfinishedTodos 换成 todos,点击修改标题就会在控制台打印 "render".*/ }
- {this.props.store.unfinishedTodos.map(
- (todo,index) => <li key={index}>{todo.title}</li>
- )}
- </ul>
- <div>
- <input type="button" onClick={() => {
- this.props.store.changeTodoTitle({index:0,title:"修改后的todo标题"});
- }} value="修改标题"/>
- </div>
- </div>
- )
- }
- }
- const store = new Store();
- render(
- <TodoBox store={store} />,
- document.getElementById('root')
- );
二十七、报Error: Plugin/Preset files are not allowed to export objects, only functions.错误的解决方案
原因是 package.json 依赖包中既有 babel 7.0 版本,又有 babel 6.0 版本,就会报这个错误
解决方案:要么全部bebel相关的包升级到7.0,要么全部降级到6.0版的,再不行检查一下全部安装的babel版本,删除node_modules重新装包
react使用过程中常见问题的更多相关文章
- (转)CloudStack 安装及使用过程中常见问题汇总
CloudStack 安装及使用过程中常见问题汇总 在做工程项目中对CloudStack 安装及使用过程中常见的几个问题及如何解决做一个总结. 1.Windows XP虚拟 ...
- Vue使用过程中常见问题
目录 一.vue监听不到state数组/json对象内的元素的值的变化,要手动通知触发 二.vue用splice删除多维数组元素导致视图更新失败情况 三.vue项目如何部署到php或者java环境的服 ...
- Android Studio使用过程中常见问题及解决方案
熟悉Android的童鞋应该对Android Studio都不陌生.Android编程有两个常用的开发环境,分别是Android Studio和Eclipse,之前使用比较多的是Eclipse,而现在 ...
- 【FAQ】接入HMS Core地图服务过程中常见问题总结
HMS Core地图服务(Map Kit)给开发者提供一套地图开发调用的SDK,助力全球开发者实现个性化地图呈现与交互,方便轻松地在应用中集成地图相关的功能,全方位提升用户体验. 在日常工作中,我们会 ...
- 【FAQ】运动健康服务REST API接口使用过程中常见问题和解决方法总结
华为运动健康服务(HUAWEI Health Kit)为三方生态应用提供了REST API接口,通过其接口可访问数据库,为用户提供运动健康类数据服务.在实际的集成过程中,开发者们可能会遇到各种问题,这 ...
- js/jQuery使用过程中常见问题
目录 一.jQuery选择器选择选中的或者disabled的选择框时attr函数无效 二.jQuery each函数的break/continue 三.jQuery 获取元素的left会值/left数 ...
- js/jQuery使用过程中常见问题/已踩过的坑大杂烩
目录 一.jQuery选择器选择选中的或者disabled的选择框时attr函数无效 二.jQuery each函数的break/continue 三.jQuery 获取元素的left会值/left数 ...
- Android无线测试之—Genymotion配置过程中常见问题
一.前提条件: 已经部署好了Android UiAutomator测试环境. 二.在部署Genymotion时遇到了两类问题: 1.通过eclipse打开一个模拟设备,然后将编译好的jar包push到 ...
- Linux使用过程中常见问题及其解决方法
“我不怕问题的出现,相反,我喜欢问题,因为我知道这是一种成长............” 1,ubuntu中文输入法的安装: 今天重装了英文版的ubuntu,而发现中文输入法并没有自动安装好,于是搜了 ...
随机推荐
- JSON使用与类型转换
JSON语法与对象 JSON方法与使用 一.JSON语法与对象 JSON是英文JavaScript Object Notation(JavaScript 对象表示法)的缩写,是存储和交换文本信息的语法 ...
- Kubernetes基本功能
说明 目前kubernetes的资料介绍很多也很深刻,本文只是做一个针对自己学习k8s过程的介绍,仅仅是学习笔记的记录. 一.基本使用 1. 命令行 集群信息 Namespace 信息 Control ...
- python3 练手实例3 摄氏温度与华氏温度转换
def wd(): w=input('请输入一个摄氏温度或者一个华氏温度,如,34c/C or 34f/F:') if w[-1] in ['c','C']: w=float(w[:-1]) hs=1 ...
- 13、Ajax的使用
一.AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. a).AJAX = 异步 JavaScript 和 XML. b).AJAX 是一种用于创建快速动态网页的技术. 通过在后 ...
- Swift 4 关于Darwin这个Module
大家在做app或者framework的时候经常会用到生成随机数的方法arc4random系列,或者取绝对值abs()等.所以我有一次好奇的想看看在Developer Document里 是怎么描述这些 ...
- 读取FTP上的某个文本文档内容到本地
/// <summary> /// 读取FTP服务器文本内容 /// </summary> /// <param name="strPath"> ...
- java中import详解
前言 import与package机制相关,这里先从package入手,再讲述import以及static import的作用. package package名称就像是我们的姓,而class名称就像 ...
- [精品书单]3D打印机课程设计
3D打印机整个绘图过程........... 三维图 工程图 编程
- Appnium-API-Status
Status Java:// TODO Python:selenium.webdriver.common.utils.is_url_connectable(port) Description Retu ...
- Cardinality
Cardinality: 优化器在计算成本的时候,需要从统计信息中取得数据,然后去估计每一步操作所涉及的行数,叫做Cardinality. 比如,一张表T有1000行数据,列COL1上没有直方图,没有 ...